2016-03-03 12 views
11

Tôi đang sử dụng DCPcrypt và SHA512 cho chuỗi băm.DCPcrypt Hashing Đức Umlauts

Tôi đang sử dụng phiên bản Warren Postma https://bitbucket.org/wpostma/dcpcrypt2010

Nó đang làm việc tốt. Tuy nhiên nó thất bại với tiếng umlauts của Đức như ä, ö, ü và có lẽ là các unicode khác.

Tôi đang sử dụng thư viện như thế này:

function TForm1.genhash(str: string): string; 
var 
    Hash : TDCP_sha512; 
    Digest: array[0..63] of byte; 
    i: integer; 
    s: string; 
begin 
    s:= ''; 
    hash := TDCP_sha512.Create(nil); 
    if hash<>nil then 
    begin 
    try 
     Hash.Init; 
     Hash.UpdateStr(str); 
     Hash.Final(Digest); 

     for i:= 0 to length(Digest)-1 do 
     s:= s + IntToHex(Digest[i],2); 

    finally 
     hash.free; 
    end; 

    end; 
    Result := s; 
end; 

Khi tôi vào thư ä tôi mong đợi đầu ra là:

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

Tôi đã kiểm tra nó với những các trang web: http://hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/

Tuy nhiên tôi nhận được:

1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A

Vì vậy, câu hỏi của tôi là: Làm thế nào tôi có thể sử dụng thư viện DCPcrypt để tạo ra băm cho umlauts Đức? THanks

Trả lời

18

Đây phải là sai lầm phổ biến nhất mà mọi người thực hiện với băm và mã hóa. Các thuật toán này hoạt động trên dữ liệu nhị phân, nhưng bạn đang chuyển văn bản. Một cái gì đó ở đâu đó đã phải mã hóa văn bản đó dưới dạng nhị phân. Và mã hóa nào nên được sử dụng. Làm thế nào để bạn biết rằng thư viện của bạn sử dụng giống như công cụ trực tuyến? Bạn không.

Vì vậy, đây là quy tắc để bạn theo dõi. Không bao giờ băm văn bản. Chỉ cần không làm điều đó. Mã hóa văn bản dưới dạng nhị phân bằng cách sử dụng mã hóa được xác định rõ ràng, được chọn rõ ràng. Và băm đó. Tôi đề nghị bạn mã hóa như là UTF-8 và băm đó. Vì vậy, TEncoding.UTF8.GetBytes(...) là bạn của bạn ở đây.

Bây giờ, nhìn vào các chi tiết thực tế ở đây, bạn đang gọi phương pháp này:

procedure UpdateStr(const Str: RawByteString); 

Tham số RawByteString, có nghĩa là văn bản Unicode của bạn đang được chuyển đổi thành một chuỗi ANSI, với trang mã hệ thống mặc định. Tôi chắc chắn đó không phải là những gì bạn dự định sẽ xảy ra. Thật vậy trình biên dịch nói điều này:

[Cảnh báo dcc32] W1058 Implicit chuỗi dàn diễn viên với sự mất mát dữ liệu tiềm năng từ 'string' thành 'RawByteString'

Vì vậy, trình biên dịch được thông báo rằng bạn đang làm điều gì sai . Bạn thực sự phải chú ý tốt đến các thông điệp của trình biên dịch.

Bây giờ, bạn có thể gọi UpdateUnicodeStr thay vì UpdateStr. Nhưng một lần nữa, làm thế nào để bạn biết mã hóa nào được sử dụng? Nó xảy ra là mã hóa nội bộ gốc, UTF-16LE.

Nhưng, hãy tuân theo quy tắc của tôi về việc không bao giờ mã hóa văn bản.

{$APPTYPE CONSOLE} 

uses 
    SysUtils, Classes, DCPsha512; 

function genhash(str: string): string; 
var 
    Bytes: TBytes; 
    Hash: TDCP_sha512; 
    Digest: array[0..63] of byte; 
begin 
    Bytes := TEncoding.UTF8.GetBytes(str); // encode text as UTF-8 bytes 

    hash := TDCP_sha512.Create(nil); 
    try 
    Hash.Init; 
    Hash.Update(Pointer(Bytes)^, Length(Bytes)); 
    Hash.Final(Digest); 
    finally 
    hash.Free; 
    end; 

    // convert the digest to a hex hash string 
    SetLength(Result, Length(Digest)*2); 
    BinToHex(Digest, PChar(Result), Length(Digest)); 
end; 

begin 
    Writeln(genhash('ä')); 
    Readln; 
end. 

Output

64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157

Lưu ý rằng tôi đơn giản hóa mã trong một số cách khác. Tôi đã xóa biến chuỗi cục bộ và làm việc trực tiếp với Result. Tôi đã sử dụng BinToHex từ đơn vị Classes để thực hiện việc phân tích thành chuyển đổi hex. Tôi cũng đã thay đổi mã này:

hash := TDCP_sha512.Create(nil); 
if hash<>nil then 
    .... 

để xóa câu hỏi if không cần thiết. Nếu một constructor không thành công, một ngoại lệ được nâng lên.

Vui lòng làm theo quy tắc của tôi không bao giờ để băm văn bản. Nó sẽ phục vụ bạn tốt!

+1

Cảm ơn David vì câu trả lời tuyệt vời này. Đánh giá cao sự giải thích và chắc chắn đã học được điều gì đó! – Tommy

+2

Tuyệt vời. Và cảm ơn bạn đã đặt câu hỏi. Thật tuyệt khi nhận được một tuyên bố rõ ràng về vấn đề này, và có cơ hội để cuối cùng viết ra những gì đã được nagging đi với tôi một thời gian. Tôi hy vọng rằng chúng tôi có thể sử dụng phần Hỏi & Đáp này để truyền bá từ về nhị phân và văn bản với băm và mã hóa! –