2015-04-15 3 views
0

Функция IndyBytesToString дает мне смешные результаты, то есть не тот, который я ожидаю.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, здесь 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

Смежные вопросы