2015-04-15 61 views
0

Indy函数BytesToString给了我有趣的结果,即不是我期待的结果。BytesToString没有给出预期的输出

这是我的代码;

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; 

该函数被调用如此;

HashSamsung('0000', 988796901418269782);

现在,当代码达到ShowMessage电话,结果是在这两个消息框不同。消息框的输出是BytesToString; FFFD2EFFFD0.....bintoascii消息框的输出是; ab2ec50e0f.....

第二个结果是我期待的结果。所以我的问题是,为什么BytesToString函数给bintoascii函数提供了不同的结果?

回答

1
  • 您的bintoAscii函数将字节解释为ANSI编码。
  • 您使用BytesToString将字节视为UTF-8编码。

由于您使用了不同的文本编码,因此您可能会得到不同的输出结果。

我不知道你在努力达到什么目的。但是,您似乎试图将二进制数据存储到字符串变量中,这总是错误的。

+0

那么我该如何让'BytesToString'使用ANSI编码呢? –

+0

['IndyTextEncoding_OSDefault'](http://stackoverflow.com/questions/25030477/encoding-in-indy-10-and-delphi)我想。它看起来很像你错误地做了这件事。你不应该把二进制数据放入字符串中。 –

+0

除非你想阅读二进制数据出于某种原因 - 我还没有遇到或知道谁可以这样做。 –

2

other question基于Python脚本示例值,这里是一个Delphi编译产生相同的输出:

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; 

或者:

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; 

无论哪种方式,这里是输出:

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

DC59AACF2AFCE72E737190323022FFB6E2831446