0

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.

5
  • 1
    Probably you are accessing on of the arrays out of bounds. Enable range checking. Commented Oct 30, 2018 at 21:41
  • The first for loop that initializes S[i] looks dodgy Commented Oct 30, 2018 at 21:48
  • This looks dodgy: key_length := length(key); key_length := key_length;. What is that good for? Commented Oct 30, 2018 at 22:30
  • Your use of 0-255 or 1-256 is very likely the problem. Strings are one-based, but dynamic arrays are not. In your previous question about the same program (under the name "Habib C", i.e. with a space) you work with fixed size arrays. That is better for your problem. Anyway, the previous question has an answer, and that works well. Commented Oct 31, 2018 at 7:44
  • For instance: for i := 0 to 256 do is most definitely wrong. Why don't you copy the Python program (from your previous question) a little closer? And, as David says, turn on range checking. Commented Oct 31, 2018 at 7:48

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

FWIW, also read my answer to your other question under the name "Habib C" instead of "HabibC": stackoverflow.com/questions/53053176/… . Why did you sign in under two almost similar names, just to ask a similar question?
Thank you very much. For some reason I was writing code to encrypt things with 'Key' being the key, instead of the general case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.