0

The Indy function BytesToString is giving me funny results, i.e. not the one I am expecting.

Here is my code;

function String2Hex(S: String): String;
var I: Integer;
begin
  Result:= '';
  for I := 1 to length (S) do
    Result:= Result+IntToHex(ord(S[i]),2);
end;

function SHA1FromString(AString:AnsiString): TidBytes;
var
  SHA1: TIdHashSHA1;
begin
  SHA1 := TIdHashSHA1.Create;
  try
    //Result := SHA1.HashBytes(AString);
    Result := SHA1.HashString(AString, IndyTextEncoding_UTF8)
   // SHA1.HashStringAsHex(UTF8Encode(AString), IndyTextEncoding_UTF8);

  finally
    SHA1.Free;
  end;
end;

function bintoAscii(bin: array of byte): AnsiString;
var i: integer;
begin
  SetLength(Result, Length(bin));
  for i := 0 to Length(bin)-1 do
    Result[1+i] := AnsiChar(bin[i]);
end;

function HashSamsung(passcode: String; salt: Int64):AnsiString;
var
  salted_pass : AnsiString;
  g_digest:AnsiString;
  buf: TidBytes;
  I: Integer;
  step: tIDBytes;
  step2: AnsiString;
  salt_hex: AnsiString;
  a: AnsiString;
begin
  salt_Hex := LowerCase(IntToHex(salt, 2));


  salted_pass := passcode + salt_hex;
  buf := nil;
  step := nil;
  for I := 0 to 1023 do
  begin

    step2 := BytesToString(buf,IndyTextEncoding_UTF8) + IntToStr(i) + salted_pass;

    buf := SHA1FromString(step2);

    showmessage(String2Hex(BytesToString(buf,IndyTextEncoding_UTF8)));
    showmessage(String2Hex(bintoAscii(buf)));

  end;
  // showmessage(String2Hex(bintoAscii(buf) ));
 // Result := String2Hex(bintoAscii(buf));
 //Result := buf;

end;

The function is called as so;

HashSamsung('0000', 988796901418269782);

Now, when the code reaches the ShowMessage calls, the results are different on both message boxes. The output from the BytesToString message box is; FFFD2EFFFD0..... and the output from the bintoascii message box is; ab2ec50e0f.....

The second result is the one I am expecting. So my question is, why is the BytesToString function giving a different result to the bintoascii function?

Jake Evans
  • 978
  • 5
  • 13
  • 33

2 Answers2

2

Based on the python script and example values in your other question, here is a Delphi translation that produces the same output:

function HashSamsung(const Passcode: String; Salt: Int64): String;
var
  salted_pass, step: String;
  buf: TIdBytes;
  I: Integer;
  SHA1: TIdHashSHA1;
begin
  salted_pass := Passcode + LowerCase(IntToHex(Salt, 2));
  SHA1 := TIdHashSHA1.Create;
  try
    for I := 0 to 1023 do
    begin
      step := BytesToStringRaw(buf) + IntToStr(i) + salted_pass;
      buf := SHA1.HashString(step, IndyTextEncoding_8Bit);
    end;
  finally
    SHA1.Free;
  end;
  Result := ToHex(buf);
end;

Alternatively:

function HashSamsung(const Passcode: String; Salt: Int64): String;
var
  salted_pass: TIdBytes;
  buf: TIdBytes;
  I: Integer;
  SHA1: TIdHashSHA1;
begin
  salted_pass := IndyTextEncoding_8Bit.GetBytes(Passcode + LowerCase(IntToHex(Salt, 2)));
  SHA1 := TIdHashSHA1.Create;
  try
    for I := 0 to 1023 do
    begin
      AppendString(buf, IntToStr(i));
      AppendBytes(buf, salted_pass);
      buf := SHA1.HashBytes(buf);
    end;
  finally
    SHA1.Free;
  end;
  Result := ToHex(buf);
end;

Either way, here is the output:

procedure Test;
begin
  ShowMessage(HashSamsung('1234', 988796901418269782));
end;

DC59AACF2AFCE72E737190323022FFB6E2831446

Community
  • 1
  • 1
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
1
  • Your bintoAscii function interprets the bytes as if they are ANSI encoded.
  • You use of BytesToString treats the bytes as if they were UTF-8 encoded.

Since you've used different text encodings, you can expect different output.

I don't know what you are trying to achieve. However it seems that you are attempting to store binary data into string variables, which is invariably wrong.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490