Форум: "Основная";
Текущий архив: 2002.11.14;
Скачать: [xml.tar.bz2];
ВнизЦиклический сдвиг вправо и влево Найти похожие ветки
← →
down (2002-11-02 16:00) [40]
> За идиота спасибо, конечно. :(
Это книжки у нас такие продаются, я тебя идиотом не считаю, ok?
Кстати, может быть, не "... для идиотов", а "... для чайников"... Но "... для идиотов" тоже что-то вроде было...
Про то, как установить точку останова, я сказал не совсем правильно, извини. Нужно нажать правой кнопкой на требуемой строчке, потом в меню выбрать Debug -> Toggle breakpoint (или F5).
Точку останова нужно поставить в строке, выполняемой до того, как проявляется ошибка. Если у тебя ошибка проявляется при нажатии кнопки шифрования, то поставь ее на месте (*), там должна появиться красная точка.
begin
(*) param1 := 3;
param2 := 1;
Code (True)
end
Если при нажатии на кнопку выполняется эта процедура, то программа остановится на строчке (*), никаких окошек до этого показываться не должно. Далее нажимаешь Ф7, пока не дойдешь до ошибки.
← →
DelphiDummy (2002-11-02 17:06) [41]Кажется я понял, в чем дело. Но, может быть, это мне только кажется. У меня есть в программе такая строчка:
for j := 1 to param1 do for i := 0 to 8 do Block[i] := Fun (Block, i);
По идее, это неправильно, ведь так? Получается, что при выполнении цикла для j во второй раз массив Block начнет заполняться заново, а в этом нет никакого смысла.
В связи с этим еще один вопрос (надеюсь, его решение поможет мне наконец-то отладить программу). В аналогичной программе на Builder`е эта строка выглядит так:
for (j = 1; j < param1; j++)
for (i = 0; i < 8; i++) Block := Fun (Block, i);
Здесь Fun -- это отдельная функция, объявленная следующим образом:
unsigned __int32* __fastcall TForm1::Fun(unsigned __int32 Block[], int ii)
Как видно, у нее есть параметр типа Cardinal -- это динамический массив Block. А сама функция тоже типа Cardinal. Почему-то Builder прекрасно принимает строчку Block := Fun (Block, i), а Delphi пишет, что нельзя типу array присвоить значение Cardinal.
Вопрос: как с этим бороться? Почему в Builder`е проходит Block := Fun (Block, i), а в Delphi не проходит?
Спасибо!
← →
Anatoly Podgoretsky (2002-11-02 17:20) [42]Все зависит от того, что такое Block, Fun и что делается внутри Fun может и не совсем бессмысленно.
← →
down (2002-11-02 17:33) [43]В Делфи массивы объявляются по-другому, нужно писать
type
CardinalArr = array of Cardinal;
function Fun(Block: CardinalArr; I: Integer): CardinalArr;
← →
DelphiDummy (2002-11-02 19:07) [44]А есть большая разница, если я написал проще в Delphi?
procedure Fun (Block: Array of Cardinal; I: Integer): Cardinal;
Хотя в этом случае тип функции Fun получается Cardinal, и когда я пишу потом Block := Fun (Block, i), копилятор пишет, что нельзя array присвоить Cardinal.
КСТАТИ! Забыл сказать: в программе на Builder`е в конце функции Fun написано return Block. То есть, в конце возвращается не значение Fun, а значение Block. Может это на что-то влияет?
Anatoly Podgoretsky (02.11.02 17:20)
> Все зависит от того, что такое Block, Fun и что делается
> внутри Fun может и не совсем бессмысленно.
Block -- это динамический массив типа Cardinal, Fun -- это цикловая функция, объявленная как Fun (Block: Array of Cardinal; I: Integer): Cardinal; То, что делается внутри Fun, приведу ниже:
function TMain_Form.Fun (Block: array of Cardinal; ii: Integer): Cardinal;
var
S: Cardinal; // число S
Mask1, Mask2: Cardinal; // маски для получения необходимых бит числа S
Si: Cardinal; // биты числа S
n: Integer;
begin
Mask1 := 15;
Mask2 := (num - 1);
Mask2 := Mask2 shr 4;
S := (Block[0] + key[ii]) div num; // получаем число S
for n := 0 to 8 do
begin
Mask1 := ror (Mask1, 4); // циклический сдвиг вправо маски
Si := (S and Mask1); // получаем необходимые биты числа S
Si := (Si shr 4 * (7 - n)); // преобразуем в 4х битное число
S := (S and Mask2); // обнуляем использованные биты S
Si := MatrixV[ii, Si]; // получаем новые биты
Si := (Si shl 4 * (7 - n)); // смещаем их в необходимую позицию
S := (S or Si); // получаем новое значение S
Mask2 := ror (Mask2, 4)
end;
S := rol (S, 11); // осуществляем циклический сдвиг влево
S := (S xor Block[1]); // получаем новое значение S
Block[1] := Block[0]; // правый блок получает значение левого
Block[0] := S // левый блок получает значение S
end;
Вот. Это что-нибудь решает?
← →
down (2002-11-02 19:59) [45]А что твоя функция должна возвращать, массив или одно значение? Если одно, то как ты массиву присваиваешь ее результат? Если же она возвращает массив, то так и надо писать.
Включи range checking (Project -> Options -> Compiler -> Runtime errors), явно с массивами не то творишь.
← →
Anatoly Podgoretsky (2002-11-02 20:03) [46]Я не берусь разбираться с функцией, куча глобальных переменных, но в целом это бред, нет возвращаемого значения, тебя жлдэен был ругать компилятор.
А то что нельзя присвоить массиву значение другого типа, то компилятор абсолютно прав.
Значит твоя задача состоит в том, что бы разобраться как работает программа на Билдере и написать ПРАВИЛЬНУЮ реализацию на Дельфи.
Вообще то для начала надо садиться за учебники по Паскалю и по тому языку который используется в Билдере, без этого толку не будет.
Другое решение заказать разработку у профессионального Дельфи программиста.
← →
TTCustomDelphiMaster (2002-11-02 20:09) [47]type
CardinalArr = array of Cardinal;
procedure Fun(var Block: CardinalArr; I: Integer);
begin
end;
← →
DelphiDummy (2002-11-02 20:12) [48]Да, Анатолий, Вы правы! Я с Вами согласен, что нужно садиться за учебники. Только проблема в том, что нет времени за них садиться. Не знаю, учились ли Вы в университете, и, если учились, то в каком городе это было, но в нашем университете вот есть такие преподаватели, которые дают лабораторную работу, а как ее сделать -- не объясняют, причем совсем, и даже не помогают, когда их попросишь. Все сам! А как я могу сам, если нам Delphi преподавали без году неделя?
Как работает программа на Builder`е,я вроде разобрался. Я же говорю, переписал на Delphi в точности, учтя то, что в Delphi нет некоторых функций, которые есть в Delphi. И программа запускается. Просто ошибки после запуска отловить труднее, чем ошибки компилятора.
А Вы, Анатолий, вместо того, чтобы давать такие советы, до которых я и сам могу додуматься, лучше бы взяли и посмотрели на обе моих программы. Я же предложил прислать эти программы. Если Вы так хорошо разбираетесь в Delphi, я думаю, для Вас не составит труда найти мою ошибку. Правильно? Ну, так что, присылать?
← →
DelphiDummy (2002-11-02 20:16) [49]Короче! Во избежание дальнейшего размусоливания той темы, которую я затронул, привожу примеры этой функции на Builder`е (работающая) и на Delphi (с глюком).
На Builder`е:
//работа цикловой функции
unsigned __int32* __fastcall TForm1::Fun(unsigned __int32 Block[], int ii)
{
unsigned __int32 S;//число S
unsigned __int32 Mask1=15,Mask2=(num-1);//маски для получения
//необходимых бит числа S
unsigned __int32 Si;//биты числа S
unsigned int n;
Mask2=Mask2>>4;
S=(Block[0]+key[ii])%num;//получаем число S
for (n=0;n<8;n++)
{
Mask1=_lrotr(Mask1,4);//циклический сдвиг вправо маски
Si=(S&Mask1);//получаем необходимые биты числа S
Si=(Si>>4*(7-n));//преобразуем в 4х битное число
S=(S&Mask2);//обнуляем использованные биты S
Si=MatrixV[ii][Si];//получаем новые биты
Si=(Si<<4*(7-n));//смещаем их в необходимую позицию
S=(S|Si);//получаем новое значение S
Mask2=_lrotr(Mask2,4);
}
S=_lrotl(S,11);//осуществляем циклический сдвиг влево
S^=Block[1];//получаем новое значение S
Block[1]=Block[0];//правый блок получает значение левого
Block[0]=S;//левый блок получает значение S
return Block;
}
На Delphi:
function TMain_Form.Fun (Block: CardinalArr; ii: Integer): CardinalArr;
var
S: Cardinal; // число S
Mask1, Mask2: Cardinal; // маски для получения необходимых бит числа S
Si: Cardinal; // биты числа S
n: Integer;
begin
Mask1 := 15;
Mask2 := (num - 1);
Mask2 := Mask2 shr 4;
S := (Block[0] + key[ii]) div num; // получаем число S
for n := 0 to 8 do
begin
Mask1 := ror (Mask1, 4); // циклический сдвиг вправо маски
Si := (S and Mask1); // получаем необходимые биты числа S
Si := (Si shr 4 * (7 - n)); // преобразуем в 4х битное число
S := (S and Mask2); // обнуляем использованные биты S
Si := MatrixV[ii, Si]; // получаем новые биты
Si := (Si shl 4 * (7 - n)); // смещаем их в необходимую позицию
S := (S or Si); // получаем новое значение S
Mask2 := ror (Mask2, 4)
end;
S := rol (S, 11); // осуществляем циклический сдвиг влево
S := (S xor Block[1]); // получаем новое значение S
Block[1] := Block[0]; // правый блок получает значение левого
Block[0] := S // левый блок получает значение S
end;
Вот! Что именно здесь неправильно?
← →
down (2002-11-02 20:37) [50]Так AV где выдается, в какой строчке? Range checking включил?
← →
DelphiDummy (2002-11-03 00:44) [51]Range Checking я включил, то есть, галочку где надо поставил. А что такое AV? Если Вы имеете в виду Access violation, то эта ошибка у меня выдается после нескольких выполнений функции Fun. Курсор становится на слове begin в функции Fun.
Чтобы было понятнее, я ниже приведу всю цепочку, по которой передается управление.
{------------------------------------------------------------------------------}
(* Работа цикловой функции. *)
function TMain_Form.Fun (Block: CardinalArr; ii: Integer): CardinalArr;
var
S: Cardinal; // число S
Mask1, Mask2: Cardinal; // маски для получения необходимых бит числа S
Si: Cardinal; // биты числа S
n: Integer;
begin
Mask1 := 15;
Mask2 := (num - 1);
Mask2 := Mask2 shr 4;
S := (Block[0] + key[ii]) div num; // получаем число S
for n := 0 to 8 do
begin
Mask1 := ror (Mask1, 4); // циклический сдвиг вправо маски
Si := (S and Mask1); // получаем необходимые биты числа S
Si := (Si shr 4 * (7 - n)); // преобразуем в 4х битное число
S := (S and Mask2); // обнуляем использованные биты S
Si := MatrixV[ii, Si]; // получаем новые биты
Si := (Si shl 4 * (7 - n)); // смещаем их в необходимую позицию
S := (S or Si); // получаем новое значение S
Mask2 := ror (Mask2, 4)
end;
S := rol (S, 11); // осуществляем циклический сдвиг влево
S := (S xor Block[1]); // получаем новое значение S
Block[1] := Block[0]; // правый блок получает значение левого
Block[0] := S // левый блок получает значение S
end;
{------------------------------------------------------------------------------}
(* Шифрование и дешифрование в режиме простой замены. *)
function TMain_Form.ECBCode (Block: CardinalArr): Cardinal;
var
RL: Cardinal;
i, j: Integer;
begin
//применяем цикловую функцию
for j := 1 to param1 do for i := 0 to 8 do Block := Fun (Block, i);
for j := 1 to param2 do for i := 7 downto 0 do Block := Fun (Block, i);
//обмениваем зашифрованные блоки
RL := Block[0];
Block[0] := Block[1];
Block[1] := RL
end;
{------------------------------------------------------------------------------}
(* Шифрование и дешифрование в режиме гаммирования. *)
procedure TMain_Form.GammaCode;
begin
Gamma[0] := (Gamma[0] + const1) div num; // получаем новый правый блок гаммы
Gamma[1] := (Gamma[1] + const2) div (num - 1); // получаем новый левый блок гаммы
GammaEncoded[0] := Gamma[0];
GammaEncoded[1] := Gamma[1];
ECBCode (Gamma); // шифруем гамму в режиме ЕСВ
IOBlock[0] := (IOBlock[0] xor GammaEncoded[0]); // накладываем гамму на левый блок вх. текста
IOBlock[1] := (IOBlock[1] xor GammaEncoded[1]) // накладываем гамму на правый блок вх. текста
end;
Вот! Если что непонятно здесь, спрашивайте.
P.S. Знать бы хоть, есть ли хоть какая-нибудь надежда отладить эту программу так, чтобы она правильно работала?.. Эх...
← →
down (2002-11-03 10:39) [52]Ладно, высылай свою программу на assorm@mail.ru, как отошлешь, напиши сюда.
← →
DelphiDummy (2002-11-03 12:48) [53]Я отослал обе программы: и ту, которая на Builder`е -- это исходная программа, и ту, которая моя на Delphi -- это та, которую написал я сам, стараясь, чтобы она в точности повторяла билдеровскую.
Спасибо, что согласился помочь.
← →
Yegor Derevenets (2002-11-03 15:20) [54]Скорее всего, я сегодня тормоз...
В паскале родном это shl, shr...
P.S. ActiveTCL рулит!!!
Страницы: 1 2 вся ветка
Форум: "Основная";
Текущий архив: 2002.11.14;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.01 c