将整数类型数组的动态数组分配给整数类型数组的变量时遇到访问错误。 PRGA函数返回一个整数数组。
有问题的行是:
keystream := PRGA(S, length(plaintext));
这是完整的代码:
program rc4;
uses
sysutils, strutils;
type
myArray = array[0..255] of integer;
dynamicArray = array of integer;
dynamicArrayString = array of string;
var
S : myArray;
keystream, cipher : dynamicArray;
hexCipher : dynamicArrayString;
key, plaintext, cipherString : string;
i, sizeOfArray, sizeOfHexArray : integer;
function KSA(key : AnsiString) : myArray;
var
i, j, key_length, temp, interJ: integer;
begin
key_length := length(key);
key_length := key_length;
interJ := 0;
j := 0;
temp := 0;
for i := 0 to 256 do
S[i] := i;
for i := 1 to 256 do // allows access to first element of ansistring.
begin // key[0] cannot be accessed
interJ := i mod key_length;
if interJ = 0 then // if interJ is 0, key[0] cannot be accessed
interJ := 3; // 3 mod 3 = 0
j := ((j + S[i-1] + ord(key[interJ])) mod 256);
temp := S[i-1];
S[i-1] := S[j];
S[j] := temp;
end;
KSA := S;
end;
function PRGA(S : myArray; n : integer) : dynamicArray;
var
i, j, K, temp, sizeOfArray : integer;
key : dynamicArray;
begin
i := 0;
j := 0;
K := 0;
temp := 0;
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
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
sizeOfArray := 0;
key := 'Key';
plaintext := 'Plaintext';
S := KSA(key);
keystream := PRGA(S, length(plaintext));
for i := 0 to (length(plaintext) - 1) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(cipher, sizeOfArray);
cipher[i] := ((keystream[i]) xor (ord(plaintext[i+1])));
end;
sizeOfHexArray := 0;
for i := 0 to sizeOfArray - 1 do
begin
sizeOfHexArray := sizeOfHexArray + 1;
SetLength(hexCipher, sizeOfHexArray);
hexCipher[i] := IntToHex(cipher[i], 2);
end;
cipherString := '';
for i := 0 to sizeOfHexArray - 1 do
begin
cipherString := cipherString + hexCipher[i];
end;
writeln(cipherString);
end.
我认为这是因为keystream变量的大小没有大小。但是,使用SetLength(keystream,length(plaintext))
仍然会导致访问冲突。
答案 0 :(得分:1)
有个好消息。您根本不需要hexCipher数组。只要做:
cipherString := '';
for I := 0 to High(cipher) do
cipherString := cipherString + IntToHex(cipher[I], 2);
但是程序中存在很多一次性错误。看看KSA。我重写了一下:
function KSA(const key: AnsiString): myArray;
var
i, j, key_length, temp: integer;
begin
key_length := length(key);
j := 0;
for i := Low(S) to High(S) do
S[i] := i;
for i := Low(S) to High(S) do
begin
j := ((j + S[i] + ord(key[i mod key_length + 1])) mod 256);
temp := S[i];
S[i] := S[j];
S[j] := temp;
end;
KSA := S;
end;
键是一个字符串,基于一个字符串,因此您只需 add 一个即可对其进行索引。不需要interJ
。这整个1 to 256
毫无意义。您想要更改数组S
,所以请使用Low()
和High()
(也许您必须启用“ mode delphi”才能使用它们,我不知道)。使用的mod 256
确保索引j
保持在0..255
范围内。
此外,key[i mod key_length]
对于从零开始的字符串也很好,但这是Pascal,而不是Python(引用您的previous question under a different name),因此,您只需将1
添加到索引即可获取有效的AnsiString
索引:key[i mod key_length + 1]
。其他任何事情都会改变原始程序的逻辑。
一个例子:说您的密钥是'Secret'
,就像原始的Python例子一样。那么key_length
是6
,因此i mod key_length
在0..5
范围内。但是您的字符串具有索引1..6
,因此只需添加1
即可为字符串建立索引。
没有充分的理由在任何地方使用interJ := 3
。那绝对没有道理。
在其余的代码中还有其他类似的问题(一次性错误索引)。我想您可以自己解决它们。