Search code examples
hashsha256lazarus

Convert string in hash sha256


I want to convert a string in a sha256 hash using DCPCrypt. Form contains an edit to enter the string, a button to convert it and another edit to show the output sha256 hash. I have wrote this code:

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, DCPsha256, StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    DCP_sha256_1: TDCP_sha256;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { private declarations }
  public

    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

function getsha256(S: String): String;
var
    Hash: TDCP_sha256;
    Digest: array[0..31] of byte;  // sha256 produces a 256bit digest (32bytes)
    Source: string;
    i: integer;
    str1: string;
  begin
    Source:= S;  // here your string for get sha256

    if Source <> '' then
    begin
      Hash:= TDCP_sha256.Create(nil);  // create the hash
      Hash.Init;                        // initialize it
      Hash.UpdateStr(Source);
      Hash.Final(Digest);               // produce the digest
      str1:= '';
      for i:= 0 to 31 do
        str1:= str1 + IntToHex(Digest[i],2);
      //form1.Edit2.Text:= s;                   // display the digest in lower case
      Form1.Edit2.Text:=UpperCase(str1);         // display the digest in capital letter
    end;
  end;

procedure TForm1.Button1Click(Sender: TObject);
  begin
    getsha256(Edit1.Text);  // show the sha256 of string in edit1
end;
end.

It works. Problem is that I receive a warning and a hint from lazarus.

  • Warning: Local variable "Digest" does not seems to be initialized;
  • Warning: Function result does not seem to be set.

Solution

  • The first warning is a false positive. The compiler doesn't know that Hash.Final() will fill in the Digest, and you are not initializing it yourself beforehand. A simple call to FillByte() (or even FillDWord()) will suffice:

    FillByte(Digest, SizeOf(Digest), 0);
    //FillDWord(Digest, SizeOf(Digest) div 4, 0);
    

    The second warning is correct, though. Your getsha256() function is declared to return a String, but you are not setting the function's Result at all. You should change this line:

    Form1.Edit2.Text:=UpperCase(str1);
    

    To this instead:

    Result:=UpperCase(str1);
    

    And then in TForm1.Button1Click(), change this line:

    getsha256(Edit1.Text);
    

    To this instead:

    Edit2.Text:=getsha256(Edit1.Text);