有几件事要注意:
- 当您需要无符号字节(例如用于索引)时,Java并不是很容易使用。
- 如果您在
S
和中创建了状态T
,那么您应该真正注意到这些值会发生变化,当您 使用相同的实例进行 解密时 , 会采用用于加密的状态; - 上面的代码在内存方面不是很有效,您可以轻松地重写它以获取字节数组。
- 要使用字符串,将参数重构为后
byte[]
,首先需要首先使用字符编码,例如使用String.getBytes(Charset charset)
;
为了使生活更轻松,并有一些有趣的深夜黑客,我改进了您的代码,并使用零进位字节数组对rfc6229中的单个向量进行了测试。
更新:正如micahk在下面指出的那样,使用了邪恶的C XOR交换,阻止了此代码对Java中输入的最后字节进行加密。使用常规的旧交换程序可以解决此问题。
警告
:以下代码应被视为编码练习。请使用经过严格审查的库,而不是下面的代码片段,以在您的应用程序中执行RC4(或Ron的代码4,ARC4等)。这意味着
Cipher.getInstance("RC4");在BouncyCastle中使用或ARC4类。
public class RC4 { private final byte[] S = new byte[256]; private final byte[] T = new byte[256]; private final int keylen; public RC4(final byte[] key) { if (key.length < 1 || key.length > 256) { throw new IllegalArgumentException( "key must be between 1 and 256 bytes"); } else { keylen = key.length; for (int i = 0; i < 256; i++) { S[i] = (byte) i; T[i] = key[i % keylen]; } int j = 0; byte tmp; for (int i = 0; i < 256; i++) { j = (j + S[i] + T[i]) & 0xFF; tmp = S[j]; S[j] = S[i]; S[i] = tmp; } } } public byte[] encrypt(final byte[] plaintext) { final byte[] ciphertext = new byte[plaintext.length]; int i = 0, j = 0, k, t; byte tmp; for (int counter = 0; counter < plaintext.length; counter++) { i = (i + 1) & 0xFF; j = (j + S[i]) & 0xFF; tmp = S[j]; S[j] = S[i]; S[i] = tmp; t = (S[i] + S[j]) & 0xFF; k = S[t]; ciphertext[counter] = (byte) (plaintext[counter] ^ k); } return ciphertext; } public byte[] decrypt(final byte[] ciphertext) { return encrypt(ciphertext); }}快乐的编码。



