Možná se někdy může stát, že je zapotřebí něco zašifrovat a třeba by též nebylo špatné viděl na implementaci.

Zde uvádím nejjednodušší variantu RC4, kterou jsem našel na netu napsanou v Javascriptu (zde je link: http://farhadi.ir/works/rc4) a přepsal jsem ji do Javy. Oproti implementaci v package java.crypto jako parametr předpokládá binární data (String) namísto pole bajtů, což může být zvláštní, ale funguje to.

Přikládám níže třídu, která obsahuje tento algoritmus RC4, test case plus řádnou poznámku o GNU licenci.

Pak ještě pokládám otázku, zda někdo neshledává něco na této implementaci chybného..

Pevně doufám, že tento miniaturní příspěvek může být užitečný ;-)

 

 

import java.io.UnsupportedEncodingException;

/**
 * RC4 symmetric cipher encryption/decryption Copyright (c) 2006 by Ali Farhadi.
 * released under the terms of the Gnu Public License. see the GPL for details.
 *
 * Email: ali[at]farhadi[dot]ir Website: http://farhadi.ir/
 *
 * Modification:
 *
 * Javacript implementation was rewritten into Java on December 12, 2009 by
 * Martin Lechner. Uses same variables and calculation.
 *
 * Email: martin.lechner@gmail.com
 *
 */

public class RC4 {

    /**
     * @param key
     *            binary string
     * @param pt
     *            binary string
     *
     * @return binary string
     */
    public static String encrypt(String key, String pt) {

        int[] s = new int[256];
        for (int i = 0; i < 256; i++) {
            s[i] = i;
        }
        int j = 0;
        int x;
        for (int i = 0; i < 256; i++) {
            j = (j + s[i] + key.charAt(i % key.length())) % 256;
            x = s[i];
            s[i] = s[j];
            s[j] = x;
        }
        int i = 0;
        j = 0;
        StringBuilder sb = new StringBuilder();
        for (int y = 0; y < pt.length(); y++) {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            x = s[i];
            s[i] = s[j];
            s[j] = x;
            sb.append(new String(new int[] { pt.charAt(y) ^ s[(s[i] + s[j]) % 256] }, 0, 1));
        }
        return sb.toString();
    }

    /**
     * @param key
     *            binary string
     * @param ct
     *            binary string
     *
     * @return binary string
     */
    public static String decrypt(String key, String ct) {
        return encrypt(key, ct);
    }

    /**
     * Method adds all valid character values into string.
     *
     * @return
     */
    public static String genAllBytesString() {

        StringBuilder sb = new StringBuilder(65535);
        for (char ch = 0; ch < 65535; ch++) {
            sb.append(ch);
        }
        return sb.toString();
    }

    static void test(String orig, String charset) throws UnsupportedEncodingException {

        if (charset != null) {
            orig = new String(orig.getBytes(charset), charset);
        }

        String enc = RC4.encrypt("secretkey", orig);
        String dec = RC4.decrypt("secretkey", enc);
        System.out.println(charset + " -> " + orig.equals(dec));
    }

    /**
     * Test case that checks RC4 encoding and decoding.
     *
     * @param args
     * @throws Exception
     */

    public static void main(String[] args) throws Exception {

        String data = genAllBytesString();
        test(data, null); // default
        test(data, "ISO-8859-1");
        test(data, "Windows-1250");
        test(data, "UTF8"); // correct canonical name in package java.lang,
        // java.io
        test(data, "UTF-8"); // alias of UTF8 since JDK 1.3
        test(data, "UTF-16");
        test(data, "GBK"); // Simplified Chinese
        test(data, "JIS0201"); // Japanese
        test(data, "UnicodeBig");
        test(data, "UnicodeBigUnmarked");
        test(data, "UnicodeLittle");
        test(data, "UnicodeLittleUnmarked");
        // test(data, "UTF-32"); Mostly not supported by JVM
    }
}
// ;-)