我正在尝试将RC4从Python转换为Pascal。
这是有效的Python代码(不是我写的):
def KSA(key):
key_length = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i]
return S
def PRGA(S, n):
i = 0
j = 0
key = []
while n > 0:
n = n - 1
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
K = S[(S[i] + S[j]) % 256]
key.append(K)
return key
key = 'Secret'
plaintext = 'Attack at dawn'
def preparing_key_array(s):
return [ord(c) for c in s]
key = preparing_key_array(key)
import numpy as np
S = KSA(key)
keystream = np.array(PRGA(S, len(plaintext)))
print(keystream)
plaintext = np.array([ord(i) for i in plaintext])
cipher = keystream ^ plaintext # ^ is XOR
print(cipher.astype(np.uint8).data.hex())
print([chr(c) for c in cipher])
这是我无法使用的Pascal代码:
program rc4;
uses
sysutils;
type
myArray = array[0..255] of integer;
var
S, keystream, cipher : myArray;
key, plaintext, cipherString : string;
i : integer;
function KSA(key : string) : myArray;
var
i, j, key_length, temp: integer;
begin
temp := 0;
key_length := length(key);
for i := 0 to 255 do
S[i] := i;
j := 0;
for i := 0 to 255 do
begin
j := (j + S[i] + ord(key[i mod key_length])) mod 256;
temp := s[i];
S[i] := S[j];
S[j] := temp;
end;
KSA := S;
end;
function PRGA(S : myArray ; n : integer) : myArray;
var
i, j, K, temp : integer;
key : myArray;
begin
i := 0;
j := 0;
K := 0;
temp := 0;
while n > 0 do
begin
n := n - 1;
i := (i + 1) mod 256;
j := (j + S[i]) mod 256;
temp := S[i];
S[i] := S[j];
S[j] := temp;
K := S[(S[i] + S[j]) mod 256];
key[i-1] := K;
end;
PRGA := key;
end;
begin
key := 'Key';
plaintext := 'Plaintext';
S := KSA(key);
keystream := PRGA(S, length(plaintext));
for i := 0 to high(keystream) do
begin
cipher[i] := (keystream[i] xor ord(plaintext[i]));
writeln(keystream[i]);
end;
cipherString := '';
for i := 0 to high(cipher) do
cipherString := cipherString + IntToStr(cipher[i]);
writeln(cipherString);
end.
我假设目前主要的错误是在KSA函数中,因为当我在KSA的末尾打印S数组时,在python和pascal之间得到了不同的结果。我也认为PRGA出了些问题,因为最后我得到的是否定的答案。
答案 0 :(得分:1)
Pascal中的字符串通常是基于一个的(Delphi移动编译器值得注意的例外)。如果更改,我将获得正确的输出:
j := (j + S[i] + ord(key[i mod key_length])) mod 256;
...
cipher[i] := (keystream[i] xor ord(plaintext[i]));
收件人:
j := (j + S[i] + ord(key[i mod key_length + 1])) mod 256; // note: + 1
...
cipher[i] := (keystream[i] xor ord(plaintext[i + 1])); // note: + 1
如果我这样做(例如在Delphi或FreePascal中):
key := 'Secret';
plaintext := 'Attack at dawn';
...
for I := 0 to Length(plaintext) - 1 do
Write(Format('%.2x', [Cipher[I]]));
Writeln;
我得到的密码为:
45A01F645FC35B383552544B9BF5