Advertisement
Guest User

TI3 16.11 00:01

a guest
Nov 15th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 14.77 KB | None | 0 0
  1. unit Unit2;
  2.  
  3. interface
  4.  
  5. uses
  6.    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7.    System.Classes, Vcl.Graphics,
  8.    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Math;
  9.  
  10. type
  11.    TBuffer = array [1 .. 1024 * 156] of Byte;
  12.    // TIntBuffer = array [1 .. 1024 * 512] of Byte;
  13.    ////////////TIntBuffer = array [1 .. 1024 * 32] of Integer;
  14.    TIntBuffer = array [1 .. 1024 * 156] of Integer;
  15.    // TInt64Buffer = array [1 .. 1024 * 128] of Int64;
  16.    TIntArray = array of Int64;
  17.    TBoolArray = array of Boolean;
  18.  
  19.    TForm2 = class(TForm)
  20.       mmPlainText: TMemo;
  21.       Memo2: TMemo;
  22.       Файл: TButton;
  23.       OpenDialog: TOpenDialog;
  24.       edtP: TEdit;
  25.       Button1: TButton;
  26.       Label1: TLabel;
  27.       Button2: TButton;
  28.       Label2: TLabel;
  29.       ListBox: TListBox;
  30.       Button3: TButton;
  31.       Button4: TButton;
  32.       edtG: TEdit;
  33.       Label3: TLabel;
  34.       edtX: TEdit;
  35.       Label4: TLabel;
  36.       Label5: TLabel;
  37.       Button5: TButton;
  38.       edtOpenKey: TEdit;
  39.       Label6: TLabel;
  40.       Label7: TLabel;
  41.       edtPrivateKey: TEdit;
  42.       Label8: TLabel;
  43.       edtK: TEdit;
  44.       Button6: TButton;
  45.       procedure ProcessCode(FileName: string);
  46.       procedure ФайлClick(Sender: TObject);
  47.       procedure Button1Click(Sender: TObject);
  48.       procedure Button2Click(Sender: TObject);
  49.       procedure Button4Click(Sender: TObject);
  50.       procedure edtPKeyPress(Sender: TObject; var Key: Char);
  51.       procedure CheckEnteredNumber(Sender: TObject; Ident: Char;
  52.         var Number: string; BottomLine: Integer; TopLine: Int64);
  53.       procedure FormCreate(Sender: TObject);
  54.       procedure ListBoxClick(Sender: TObject);
  55.       procedure edtXKeyPress(Sender: TObject; var Key: Char);
  56.       procedure Button3Click(Sender: TObject);
  57.       procedure Button5Click(Sender: TObject);
  58.       procedure CheckEnteredNumberExt(Sender: TObject; Ident: Char;
  59.         var Number: string; BottomLine: Integer; TopLine: Int64);
  60.       procedure edtKKeyPress(Sender: TObject; var Key: Char);
  61.       procedure Button6Click(Sender: TObject);
  62.    private
  63.       { Private declarations }
  64.    public
  65.       { Public declarations }
  66.    end;
  67.  
  68. var
  69.    Form2: TForm2;
  70.    NumberP, NumberX, NumberG, NumberK: string;
  71.    Buffer: TBuffer;
  72.    StreamSize: Int64;
  73.    fNameCipher, fNameDecipher: string;
  74.    f, fcipher, fDecipher: file;
  75.  
  76. const
  77.    AMOUNT_ROOTS = 10000;
  78.  
  79. implementation
  80.  
  81. {$R *.dfm}
  82.  
  83. function IsPrimeNumber(Number: Int64): Boolean;
  84. var
  85.    i: Integer;
  86. begin
  87.    result := false;
  88.    if not Odd(Number) and (Number <> 2) then
  89.       Exit;
  90.    i := 3;
  91.    while i <= Sqrt(Number) do
  92.    begin
  93.       if Number mod i = 0 then
  94.          Exit;
  95.       inc(i, 2);
  96.    end;
  97.    result := true;
  98. end;
  99.  
  100. procedure TForm2.Button1Click(Sender: TObject);
  101. begin
  102.    if IsPrimeNumber(StrToInt64(edtP.text)) then
  103.       Label1.caption := 'Yes';
  104. end;
  105.  
  106. function FastExp(Number, Degree, Module: Int64): Int64;
  107. var
  108.    Num, Deg, Res, TempNum: Int64;
  109. begin
  110.    Num := Number;
  111.    Deg := Degree;
  112.    Res := 1;
  113.    while Deg <> 0 do
  114.    begin
  115.       while (Deg mod 2) = 0 do
  116.       begin
  117.          Deg := Deg div 2;
  118.          TempNum := Num mod Module;
  119.          Num := (TempNum * TempNum) mod Module;
  120.       end;
  121.       Deg := Deg - 1;
  122.       Res := (Res * Num) mod Module;
  123.    end;
  124.    FastExp := Res;
  125. end;
  126.  
  127. function FastExpMul(Number, Degree, Module: Int64;
  128.   var Multiplier: Integer): Int64;
  129. var
  130.    TempRes, TempInt: Int64;
  131. begin
  132.    TempRes := FastExp(Number, Degree, Module);
  133.    TempInt := Multiplier mod Module;
  134.    FastExpMul := (TempRes * TempInt) mod Module;
  135. end;
  136.  
  137. function FastExpMulByte(Number, Degree, Module: Int64;
  138.   var Multiplier: Byte): Int64;
  139. var
  140.    TempRes, TempInt: Int64;
  141. begin
  142.    TempRes := FastExp(Number, Degree, Module);
  143.    TempInt := Multiplier mod Module;
  144.    FastExpMulByte := (TempRes * TempInt) mod Module;
  145. end;
  146.  
  147. function ExtendedGCD(a, b: Integer; var x, y, gcd: Integer): Integer;
  148. var
  149.    x1, y1: Integer;
  150. begin
  151.    If b = 0 Then
  152.    begin
  153.       gcd := a;
  154.       x := 1;
  155.       y := 0;
  156.       Exit
  157.    end;
  158.    ExtendedGCD(b, a mod b, x1, y1, gcd);
  159.    x := y1;
  160.    y := x1 - (a div b) * y1;
  161.    result := gcd;
  162. end;
  163.  
  164. function FindPrimeDividers(Number: Int64; var Amount: Int64): TIntArray;
  165. var
  166.    i, j, k: Int64;
  167.    PrimeArray, ResArray: TIntArray;
  168. begin
  169.    SetLength(PrimeArray, Number);
  170.    for i := 2 to Number do
  171.       if Number mod i = 0 then
  172.       begin
  173.          k := 0;
  174.          for j := 2 to i div 2 do
  175.             if i mod j = 0 then
  176.                k := k + 1;
  177.          if k = 0 then
  178.          begin
  179.             PrimeArray[Amount] := i;
  180.             inc(Amount);
  181.          end;
  182.       end;
  183.    SetLength(ResArray, Amount);
  184.    for i := 0 to Amount - 1 do
  185.       ResArray[i] := PrimeArray[i];
  186.    FindPrimeDividers := ResArray;
  187. end;
  188.  
  189. function FindPrimRoots(p: Int64): TIntArray;
  190. var
  191.    PrimDeviders, PrimRoots, ResArray: TIntArray;
  192.    BoolArray: TBoolArray;
  193.    i, j, PrimDivNum, PrimRootNum, TempInt: Int64;
  194. begin
  195.    SetLength(PrimDeviders, p);
  196.    SetLength(PrimRoots, p);
  197.    SetLength(BoolArray, p);
  198.    for i := 0 to p - 1 do
  199.       BoolArray[i] := true;
  200.    PrimDivNum := 0;
  201.    PrimRootNum := 0;
  202.    PrimDeviders := FindPrimeDividers(p - 1, PrimDivNum);
  203.    for i := 2 to p - 1 do
  204.    begin
  205.       for j := 1 to PrimDivNum do
  206.       begin
  207.          TempInt := FastExp(i, round((p - 1) / PrimDeviders[j - 1]), p);
  208.          if (FastExp(i, round((p - 1) / PrimDeviders[j - 1]), p) = 1) then
  209.          begin
  210.             BoolArray[i] := false;
  211.             break;
  212.          end;
  213.       end;
  214.       if BoolArray[i] = true then
  215.       begin
  216.          PrimRoots[PrimRootNum] := i;
  217.          inc(PrimRootNum);
  218.       end;
  219.    end;
  220.    SetLength(ResArray, PrimRootNum);
  221.    for i := 0 to PrimRootNum - 1 do
  222.       ResArray[i] := PrimRoots[i];
  223.    FindPrimRoots := ResArray;
  224. end;
  225.  
  226. procedure TForm2.Button2Click(Sender: TObject);
  227. var
  228.    i: Integer;
  229.    OutputArray: TIntArray;
  230.    k: Int64;
  231. begin
  232.    CheckEnteredNumber(edtP, 'p', NumberP, 257, 9223372036854775807);
  233.    CheckEnteredNumber(edtX, 'x', NumberX, 2, StrToInt64(NumberP) - 1);
  234.    CheckEnteredNumberExt(edtK, 'k', NumberK, 2, StrToInt64(NumberP) - 1);
  235.    if (NumberP <> ' ') and (NumberX <> ' ') and (NumberK <> ' ') then
  236.    begin
  237.       SetLength(OutputArray, StrToInt64(NumberP));
  238.       OutputArray := FindPrimRoots(StrToInt64(NumberP));
  239.       i := 0;
  240.       if high(OutputArray) > AMOUNT_ROOTS then
  241.          k := AMOUNT_ROOTS
  242.       else
  243.          k := high(OutputArray);
  244.       while (i <= k) do
  245.       begin
  246.          ListBox.Items.Insert(i, inttostr(OutputArray[i]));
  247.          Memo2.Lines.Add(inttostr(OutputArray[i]));
  248.          inc(i);
  249.       end;
  250.    end;
  251. end;
  252.  
  253. procedure TForm2.Button3Click(Sender: TObject);
  254. begin
  255.    CheckEnteredNumber(edtP, 'p', NumberP, 257, 9223372036854775807);
  256.    CheckEnteredNumber(edtX, 'x', NumberX, 2, StrToInt64(NumberP) - 1);
  257. end;
  258.  
  259. function IsPrimeButton(Number: Int64): Boolean;
  260. begin
  261.    if IsPrimeNumber(Number) then
  262.       result := true
  263.    else
  264.       result := false;
  265. end;
  266.  
  267. procedure TForm2.Button4Click(Sender: TObject);
  268. var
  269.    y, a, k, p, kl, t: Int64;
  270.    arr: TBuffer;
  271.    i, j: Integer;
  272.    ArrayB: TIntBuffer;
  273.    Stream: TFileStream;
  274.    Size: Integer;
  275. begin
  276.    NumberG := edtG.text;
  277.    y := FastExp(StrToInt64(edtG.text), StrToInt64(NumberX),
  278.      StrToInt64(NumberP));
  279.    edtOpenKey.text := NumberP + ', ' + NumberG + ', ' + inttostr(y);
  280.    edtPrivateKey.text := NumberX;
  281.    a := FastExp(StrToInt64(edtG.text), StrToInt64(NumberK),
  282.      StrToInt64(NumberP));
  283.    k := StrToInt64(NumberK);
  284.    p := StrToInt64(NumberP);
  285.    for i := 1 to StreamSize do
  286.    begin
  287.       arr[i] := Buffer[i];
  288.    end;
  289.    kl := StreamSize;
  290.    { i := 1;
  291.      while i <= 8 * kl do
  292.      begin
  293.      t := FastExpMul(y, k, p, arr[i]);
  294.      ArrayB[i] := a and $FF;
  295.      ArrayB[i + 1] := (a shr 8) and $FF;
  296.      ArrayB[i + 2] := (a shr $10) and $FF;
  297.      ArrayB[i + 3] := (a shr $18) and $FF;
  298.  
  299.      ArrayB[i + 4] := t and $FF;
  300.      ArrayB[i + 5] := (t shr 8) and $FF;
  301.      ArrayB[i + 6] := (t shr $10) and $FF;
  302.      ArrayB[i + 7] := (t shr $18) and $FF;
  303.  
  304.      inc(i, 8);
  305.      end; }
  306.    i := 1;
  307.    j := 1;
  308.    while i <= 2 * kl do
  309.    begin
  310.       ArrayB[i] := a;
  311.       ArrayB[i + 1] := FastExpMulByte(y, k, p, arr[j]);
  312.       inc(i, 2);
  313.       inc(j, 1);
  314.    end;
  315.    Stream := TFileStream.Create(fNameCipher, fmCreate);
  316.    Stream.Write(ArrayB[1], 2 * kl * SizeOf(Integer));
  317.    Stream.Free;
  318.    ShowMessage('Successfully ciphered');
  319. end;
  320.  
  321. procedure TForm2.Button5Click(Sender: TObject);
  322. begin
  323.    Label1.caption := inttostr(FastExp(StrToInt64(edtG.text),
  324.      StrToInt64(NumberX), StrToInt64(NumberP)));
  325. end;
  326.  
  327. procedure TForm2.Button6Click(Sender: TObject);
  328. var
  329.    y, a, k, p, kl, t: Int64;
  330.    arr: TBuffer;
  331.    i, ka: Integer;
  332.    ArrayRes: TBuffer;
  333.    ArrayB: TIntBuffer;
  334.    Stream: TFileStream;
  335.    Size: Integer;
  336.    Degr: Int64;
  337. begin
  338.    if OpenDialog.Execute then
  339.    begin
  340.       Stream := TFileStream.Create(OpenDialog.FileName, fmOpenRead);
  341.       Size := Stream.ReadData(ArrayB);
  342.       // Stream := TFileStream.Create(fNameCipher, fmCreate);
  343.       // Stream.Read(ArrayB[1], 2 * kl * SizeOf(Integer));
  344.    end;
  345.    // Size := Size div 8;
  346.    // Degr := StrToInt64(NumberX) * (StrToInt64(NumberP) - 2);
  347.    Degr := (StrToInt64(NumberP) - 1 - StrToInt64(NumberX));
  348.    i := 1;
  349.    ka := 1;
  350.    while i <= Size div 4 do
  351.    begin
  352.       // ArrayRes[ka] := FastExpMul(ArrayB[i + 1], Degr, StrToInt64(NumberP), ArrayB[i]);
  353.       ArrayRes[ka] := FastExpMul(ArrayB[i], Degr, StrToInt64(NumberP),
  354.         ArrayB[i + 1]);
  355.       inc(i, 2);
  356.       inc(ka, 1);
  357.    end;
  358.  
  359.    Stream := TFileStream.Create(fNameDecipher, fmCreate);
  360.    Stream.Write(ArrayRes[1], ka * SizeOf(byte));
  361.    Stream.Free;
  362.    ShowMessage('Successfully ciphered');
  363.  
  364.    { i := 1;
  365.      while i <= 2 * kl do
  366.      begin
  367.      ArrayB[i] := a;
  368.      ArrayB[i + 1] := FastExpMul(y, k, p, arr[i]);
  369.      inc(i, 2);
  370.      end;
  371.      Stream := TFileStream.Create(fNameCipher, fmCreate);
  372.      Stream.Write(ArrayB[1], 2 * kl * SizeOf(Integer));
  373.      Stream.Free; }
  374. end;
  375.  
  376. procedure TForm2.CheckEnteredNumber(Sender: TObject; Ident: Char;
  377.   var Number: string; BottomLine: Integer; TopLine: Int64);
  378. begin
  379.    with Sender as TEdit do
  380.       if Number <> ' ' then
  381.       begin
  382.          if (StrToInt64(Number) >= BottomLine) and (StrToInt64(Number) < TopLine)
  383.          then
  384.          begin
  385.             if IsPrimeButton(StrToInt64(Number)) then
  386.                Label1.caption := 'Yes'
  387.             else
  388.             begin
  389.                ShowMessage('Число ' + Ident + ' должно быть простым');
  390.                Number := ' ';
  391.                Clear;
  392.             end;
  393.          end
  394.          else
  395.          begin
  396.             ShowMessage('Введите число ' + Ident + ' больше ' +
  397.               inttostr(BottomLine - 1) + ' меньше ' + inttostr(TopLine));
  398.             Number := ' ';
  399.             Clear;
  400.          end;
  401.       end
  402.       else
  403.       begin
  404.          ShowMessage('Введите простое число ' + Ident);
  405.          Number := ' ';
  406.          Clear;
  407.       end;
  408. end;
  409.  
  410. procedure TForm2.CheckEnteredNumberExt(Sender: TObject; Ident: Char;
  411.   var Number: string; BottomLine: Integer; TopLine: Int64);
  412. var
  413.    x, y, gcd: Integer;
  414. begin
  415.    with Sender as TEdit do
  416.    begin
  417.       if Number <> ' ' then
  418.       begin
  419.          if (StrToInt64(Number) >= BottomLine) and (StrToInt64(Number) < TopLine)
  420.          then
  421.          begin
  422.             if IsPrimeButton(StrToInt64(Number)) then
  423.                Label1.caption := 'Yes'
  424.             else
  425.             begin
  426.                ShowMessage('Число ' + Ident + ' должно быть простым');
  427.                Number := ' ';
  428.                Clear;
  429.             end;
  430.          end
  431.          else
  432.          begin
  433.             ShowMessage('Введите число ' + Ident + ' больше ' +
  434.               inttostr(BottomLine - 1) + ' меньше ' + inttostr(TopLine));
  435.             Number := ' ';
  436.             Clear;
  437.          end;
  438.       end
  439.       else
  440.       begin
  441.          ShowMessage('Введите простое число ' + Ident);
  442.          Number := ' ';
  443.          Clear;
  444.       end;
  445.       if NumberK <> ' ' then
  446.          if ExtendedGCD(StrToInt64(NumberK), StrToInt64(NumberP) - 1, x, y,
  447.            gcd) <> 1 then
  448.          begin
  449.             ShowMessage('Введите число k взаимно простое с p - 1');
  450.             Number := ' ';
  451.             Clear;
  452.          end;
  453.    end;
  454. end;
  455.  
  456. procedure TForm2.edtKKeyPress(Sender: TObject; var Key: Char);
  457. const
  458.    Digit: set of Char = ['0' .. '9'];
  459. begin
  460.    if Key in Digit then
  461.       NumberK := NumberK + Key;
  462.    if Key = #8 then
  463.       NumberK := ' ';
  464. end;
  465.  
  466. procedure TForm2.edtPKeyPress(Sender: TObject; var Key: Char);
  467. const
  468.    Digit: set of Char = ['0' .. '9'];
  469. begin
  470.    if Key in Digit then
  471.       NumberP := NumberP + Key;
  472.    if Key = #8 then
  473.       NumberP := ' ';
  474. end;
  475.  
  476. procedure TForm2.edtXKeyPress(Sender: TObject; var Key: Char);
  477. const
  478.    Digit: set of Char = ['0' .. '9'];
  479. begin
  480.    if Key in Digit then
  481.       NumberX := NumberX + Key;
  482.    if Key = #8 then
  483.       NumberX := ' ';
  484. end;
  485.  
  486. procedure TForm2.ProcessCode(FileName: string);
  487. var
  488.    Stream: TFileStream;
  489.    FileByte: Byte;
  490.    i: Integer;
  491.    Size, ByteCounter, LinesCounter: Integer;
  492. begin
  493.    Stream := TFileStream.Create(FileName, fmOpenRead);
  494.    Size := Stream.ReadData(Buffer);
  495.    Stream.Position := 0;
  496.    ByteCounter := 0;
  497.    LinesCounter := 1;
  498.    StreamSize := Stream.Size;
  499.    for i := 0 to Stream.Size - 1 do
  500.    begin
  501.       Stream.ReadBuffer(FileByte, 1);
  502.       inc(ByteCounter);
  503.       if ByteCounter <= 8 then
  504.          mmPlainText.text := mmPlainText.text + inttostr(FileByte) + ' '
  505.       else if LinesCounter < 21 then
  506.       begin
  507.          ByteCounter := 0;
  508.          inc(LinesCounter);
  509.          mmPlainText.Lines.Add(inttostr(FileByte));
  510.          inc(ByteCounter);
  511.          mmPlainText.text := mmPlainText.text + ' ';
  512.       end;
  513.    end;
  514.    Stream.Free;
  515.  
  516.    fNameCipher := FileName;
  517.    i := Length(fNameCipher);
  518.    while fNameCipher[i] <> '.' do
  519.       Dec(i);
  520.    Insert('  CIPHER', fNameCipher, i);
  521.    Assignfile(fcipher, fNameCipher);
  522.    fNameDecipher := fNameCipher;
  523.    Insert(' DE', fNameDecipher, pos('CIPHER', fNameDecipher));
  524.    Assignfile(fDecipher, fNameDecipher);
  525. end;
  526.  
  527. procedure TForm2.ФайлClick(Sender: TObject);
  528. begin
  529.    if OpenDialog.Execute then
  530.    begin
  531.       mmPlainText.Clear;
  532.       ProcessCode(OpenDialog.FileName);
  533.    end;
  534. end;
  535.  
  536. procedure TForm2.FormCreate(Sender: TObject);
  537. begin
  538.    NumberP := ' ';
  539.    NumberX := ' ';
  540. end;
  541.  
  542. procedure TForm2.ListBoxClick(Sender: TObject);
  543. var
  544.    i: Integer;
  545. begin
  546.    for i := 0 to ListBox.Items.Count - 1 do
  547.       if ListBox.Selected[i] then
  548.          edtG.text := ListBox.Items[i];
  549. end;
  550.  
  551. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement