将RC4的Python代码转换为Pascal

时间:2018-10-29 20:16:10

标签: python encryption pascal

我正在尝试将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出了些问题,因为最后我得到的是否定的答案。

1 个答案:

答案 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