将动态数组分配给变量时发生访问冲突(Pascal)

Access violation when assigning dynamic array to variable (Pascal)

我在将整数数组类型的动态数组分配给同样是整数数组类型的变量时遇到访问错误。 PRGA函数returns一个整数数组。

有问题的行是:

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.

我假设这是因为密钥流变量的大小没有大小。但是使用 SetLength(keystream,length(plaintext)) 仍然会导致访问冲突。

有个好消息。您根本不需要 hexCipher 数组。只是做:

cipherString := '';
for I := 0 to High(cipher) do
  cipherString := cipherString + IntToHex(cipher[I], 2);

但是你的程序中有很多一次性错误。看看沙特阿拉伯。我重写了一下:

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;

Key 是一个字符串,并且是基于 one 的,所以您必须 add 一个来索引它。不需要 interJ。整个 1 to 256 事情没有意义。你想更改数组 S,所以使用 Low()High()(也许你必须启用 "mode delphi" 才能使用它们,我不知道)。使用的 mod 256 确保索引 j 保持在 0..255 范围内。

此外,key[i mod key_length] 适用于从零开始的字符串,但这是 Pascal,而不是 Python(引用您的 ),因此您必须简单地添加 1 到索引以获得有效的 AnsiString 索引:key[i mod key_length + 1]。其他任何东西都会改变原始程序的逻辑。

一个例子:假设你的密钥是 'Secret',就像原来的 Python 例子一样。那么 key_length 就是 6,所以 i mod key_length0..5 范围内。但是你的字符串有索引 1..6,所以只需添加 1 来索引字符串。

并且没有任何理由在任何地方使用 interJ := 3。这完全没有意义。

您的其余代码中还有其他类似的问题(一次性错误索引)。我想你可以自己解决它们。