Код работает так:
Когда я, нажимая на кнопку, запускаю выполнение процедуры
procedure TfMain.ButtonEncryptClick(Sender: TObject), то из поля
Memo1 считывается текст и затем обрабатывается в основном функцией
encr_decr. По окончанию в поле
Memo2 выводится зашифрованный текст методом магического квадрата. Так вот, код хорошо работает только с английскими символами, если вписать в
Memo1 русский текст, то на выводе в
Memo2 получаем краказябры и знаки вопроса.
У меня есть предположения, что в этом могут быть виноваты функция
delete и процедура
swap. Но переписав
delete я не получил ожидаемого результата, да еще и ошибки начали вылетать, в итоге вернулся обратно на функцию
delete. Вместо
delete я писал код:
for num:=1 to UTF8Length(s)-n*n do
sdel:= sdel + s[num+n*n];
s:= sdel;
Курю форумы уже два дня, но так и не понимаю, как решить проблему. Возможно, стоит как-то переписать процедуру
swap, которая работает с символами, но нет никаких представлений что там менять и надо ли вообще ее трогать.
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, LazUTF8, LConvEncoding, StdCtrls;
type
mas=array[1..10,1..10] of integer;
{ TfMain }
TfMain = class(TForm)
ButtonEncrypt: TButton;
ButtonDecrypt: TButton;
Memo1: TMemo;
Memo2: TMemo;
MemoMS: TMemo;
procedure ButtonDecryptClick(Sender: TObject);
procedure ButtonEncryptClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
fMain: TfMain;
A:mas;
i,j,n,k:integer;
lgthS:real;
s:string;
implementation
{$R *.lfm}
{ Programm }
procedure kvadrat(var A:mas;n:integer);
var
i,j:integer;
begin
for i:= 1 to n do
for j:= 1 to n do begin
a[i,j]:= 1+((i+j-1+n div 2) mod n)*n+(i+2*(j-1)) mod n;
end;
end;
procedure swap(var c1,c2:char);
var
s2:char;
begin
s2:= c1;
c1:= c2;
c2:= s2;
end;
function encr_decr(A:mas;stroka:string;enc_dec:boolean):string; // квадрат,строка,true-шифруем,false-расшифровываем
var
i,j,k,num:integer;
l:array[1..100] of integer;
sc,s1,s,sdel:string;
s2:char;
begin
s:= stroka;
k:= 0;
sdel:= '';
for i:= 1 to n do
for j:= 1 to n do
begin
k:= k+1;
l[k]:= A[i,j];
end;
if n*n>Length(s) then while Length(s)<n*n do s:= s+' ';
if Length(s) mod (n*n)>0 then while (Length(s) mod (n*n))>0 do s:= s+' ';
sc:= '';
repeat
s1:= Copy(s,1,n*n);
if enc_dec then for i:= 1 to n*n do swap(s1[i],s1[l[i]])
else for i:= n*n downto 1 do swap(s1[i],s1[l[i]]);
Delete(s,1,n*n);
sc:= sc+s1;
until UTF8Length(s)<=1;
encr_decr:= sc;
end;
{ TfMain }
procedure TfMain.FormCreate(Sender: TObject);
begin
end;
procedure TfMain.ButtonEncryptClick(Sender: TObject);
var
str: string;
begin
s:= Memo1.Text;
lgthS:= UTF8Length(s);
lgthS:= sqrt(lgthS);
n:= round(lgthS);
if n= lgthS then lgthS:= trunc(lgthS)
else lgthS:= trunc(lgthS)+1;
if lgthS<3 then lgthS:= 3;
if round(lgthS) and 1 = 0 then lgthS:= lgthS+1;
n:= round(lgthS);
kvadrat(A,n); // расчет квадрата
MemoMS.Clear;
str:= '';
for i:= 1 to n do begin
for j:= 1 to n do begin
str:= str + ' ' + IntToStr(A[i, j]);
end;
MemoMS.Lines.Add(str);
str:= '';
end;
Memo2.Text:= ( encr_decr(A,s,true) );
end;
procedure TfMain.ButtonDecryptClick(Sender: TObject);
begin
end;
end.