简体   繁体   中英

Access violation when assigning dynamic array to variable (Pascal)

I'm getting an access error when assigning a dynamic array of type array of integer to a variable also of type array of integer. The function PRGA returns an array of integer.

The line in question is:

keystream := PRGA(S, length(plaintext));

This is the full code:

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.

I assumed that it was because the size of the keystream variable did not have a size. However using SetLength(keystream,length(plaintext)) still leads to an access violation.

There is good news. You don't need the hexCipher array at all. Just do:

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

But there are many one-off errors in your program. Take a look at KSA. I rewrote it a bit:

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 is a string, and one-based, so you must just add one to index it. No need for interJ . This entire 1 to 256 thing doesn't make sense. You want to change the array S , so use Low() and High() (perhaps you must enable "mode delphi" to use those, I don't know). The mod 256 used ensures that the index j remains in the range 0..255 .

Also, key[i mod key_length] would be fine for zero-based strings, but this is Pascal, not Python (referencing your previous question under a different name ), so you must simply add 1 to the index to get a valid AnsiString index: key[i mod key_length + 1] . Anything else would change the logic of the original program.

An example: say your key is 'Secret' , as in the original Python example. Then the key_length is 6 , so i mod key_length is in the range 0..5 . But your string has indices 1..6 , so simply add 1 to index the string.

And there is no good reason whatsoever to use interJ := 3 anywhere. That makes absolutely no sense.

There are other, similar problems (one-off wrong indexes) in the rest of your code. I guess you can solve them yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM