Нарушение прав доступа при назначении динамического массива переменной (Паскаль) - PullRequest
0 голосов
/ 30 октября 2018

Я получаю ошибку доступа при назначении динамического массива типа массив целых чисел переменной также типа массив целых чисел. Функция 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.

Я предположил, что это потому, что размер переменной ключевого потока не имел размера. Однако использование SetLength(keystream,length(plaintext)) все еще приводит к нарушению доступа.

1 Ответ

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

Есть хорошие новости. Вам не нужен массив 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;

Ключ - строка, основанная на единицах, поэтому вам нужно просто добавить единицу, чтобы проиндексировать ее. Нет необходимости в interJ. Вся эта вещь 1 to 256 не имеет смысла. Вы хотите изменить массив S, поэтому используйте Low() и High() (возможно, вы должны включить «mode delphi», чтобы использовать их, я не знаю). Используемый mod 256 гарантирует, что индекс j остается в диапазоне 0..255.

Кроме того, key[i mod key_length] будет хорошо для строк, начинающихся с нуля, но это Паскаль, а не Python (ссылается на ваш предыдущий вопрос под другим именем ), поэтому вы должны просто добавить 1 в индекс для получения действительного AnsiString индекса: key[i mod key_length + 1]. Все остальное изменило бы логику оригинальной программы.

Пример: скажем, ваш ключ 'Secret', как в оригинальном примере Python. Тогда key_length равно 6, поэтому i mod key_length находится в диапазоне 0..5. Но ваша строка имеет индексы 1..6, поэтому просто добавьте 1 для индексации строки.

И нет никаких веских причин использовать interJ := 3 где-либо. Это абсолютно бессмысленно.

В остальной части вашего кода есть другие похожие проблемы (одноразовые неверные индексы). Я думаю, вы можете решить их самостоятельно.

...