Перевод кода Python для RC4 на Паскаль - PullRequest
0 голосов
/ 29 октября 2018

Я пытаюсь перевести RC4 с Python на Паскаль.

Это рабочий код 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])

Это мой нерабочий код Паскаля:

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 на данный момент, так как я получаю разные результаты между python и pascal, когда я печатаю массив S в конце KSA. Я также думаю, что с PRGA что-то не так, поскольку к концу я получаю отрицательные ответы.

1 Ответ

0 голосов
/ 31 октября 2018

Строки в 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
...