Ich versuche, einen String mit SHA256 zu hashen. Ich verwende den folgenden Code:
using System;
using System.Security.Cryptography;
using System.Text;
public class Hash
{
public static string getHashSha256(string text)
{
byte[] bytes = Encoding.Unicode.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash)
{
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
}
Dieser Code liefert jedoch signifikant andere Ergebnisse als mein Freund PHP sowie Online-Generatoren (wie dieser Generator ).
Weiß jemand, was der Fehler ist? Verschiedene Basen?
Antworten:
Encoding.Unicode
ist der irreführende Name von Microsoft für UTF-16 (eine doppelt breite Codierung, die in der Windows-Welt aus historischen Gründen verwendet wird, aber von niemand anderem verwendet wird). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspxWenn Sie Ihr
bytes
Array untersuchen, werden Sie feststellen, dass jedes zweite Byte vorhanden ist0x00
(aufgrund der doppelt breiten Codierung).Sie sollten
Encoding.UTF8.GetBytes
stattdessen verwenden.Sie sehen jedoch auch unterschiedliche Ergebnisse, je nachdem, ob Sie das Abschlussbyte
'\0'
als Teil der Daten betrachten, die Sie hashen. Das Hashing der zwei Bytes"Hi"
ergibt ein anderes Ergebnis als das Hashing der drei Bytes"Hi"
. Sie müssen sich entscheiden, was Sie tun möchten. (Vermutlich möchten Sie den PHP-Code Ihres Freundes ausführen.)Für ASCII-Text
Encoding.UTF8
wird auf jeden Fall geeignet sein. Wenn Sie eine perfekte Kompatibilität mit dem Code Ihres Freundes anstreben , auch bei Nicht-ASCII-Eingaben, sollten Sie einige Testfälle mit Nicht-ASCII-Zeichen wieé
und ausprobieren家
und prüfen, ob Ihre Ergebnisse noch übereinstimmen. Wenn nicht, müssen Sie herausfinden, welche Codierung Ihr Freund wirklich verwendet. Es könnte sich um eine der 8-Bit- "Codepages" handeln, die vor der Erfindung von Unicode populär waren. (Auch hier denke ich, dass Windows der Hauptgrund ist, warum sich noch jemand um "Codepages" sorgen muss.)quelle
short
s", aber nicht "Sortieren nach UTF16-codierten Bytes", es sei denn, Sie befinden sich auf einem Big-Endian-System, was Windows nicht ist.) "Sortieren" in Unicode ist jedoch wirklich ein kompliziertes Thema, das für einen anderen Tag gespeichert werden sollte.Ich hatte auch dieses Problem mit einem anderen Implementierungsstil, aber ich habe vergessen, woher ich es habe, seit es vor 2 Jahren war.
Wenn ich
abcdefghi2013
aus irgendeinem Grund etwas eingebe, werden unterschiedliche Ergebnisse angezeigt und Fehler in meinem Anmeldemodul angezeigt. Dann habe ich versucht, den Code auf die gleiche Weise zu ändern, wie von Quuxplusone vorgeschlagen, und die Codierung vonASCII
bis geändert, bisUTF8
es endlich funktioniert hat!Nochmals vielen Dank Quuxplusone für die wunderbare und detaillierte Antwort! :) :)
quelle
hash += bit.ToString("x2");
ich hier eine Frage habe: Ich habe verwendetConvert.ToBase64String(byte[] encryptedBytes)
, um von Bytes zurück in Zeichenfolgen zu konvertieren. das gab mir ein anderes Ergebnis. Was ist der Unterschied zwischen diesen beiden Konvertierungsmethoden von Bytes in Zeichenfolgen?Der Grund, warum Sie unterschiedliche Ergebnisse erhalten, liegt darin, dass Sie nicht dieselbe Zeichenfolgencodierung verwenden. Der Link, den Sie für die Online-Website setzen, die SHA256 berechnet, verwendet die UTF8-Codierung, während Sie in Ihrem Beispiel die Unicode-Codierung verwendet haben. Es handelt sich um zwei verschiedene Codierungen, sodass Sie nicht das gleiche Ergebnis erhalten. Mit dem obigen Beispiel erhalten Sie den gleichen SHA256-Hash der verlinkten Website. Sie müssen dieselbe Codierung auch in PHP verwenden.
Das absolute Minimum Jeder Softwareentwickler muss unbedingt über Unicode und Zeichensätze Bescheid wissen (keine Ausreden!)
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolut-positiv-must-wiss-about-unicode-and-character-sets-no-excuses/
quelle
In der PHP-Version können Sie im letzten Parameter 'true' senden, der Standardwert ist jedoch 'false'. Der folgende Algorithmus entspricht der Hash-Funktion des Standard-PHP, wenn 'sha256' als erster Parameter übergeben wird:
quelle
ASCII
undbyte[] arrBytes = System.Text.Encoding.UTF8.GetBytes(strData)
stattdessen tun .quelle
Der kürzeste und schnellste Weg aller Zeiten. Nur 1 Zeile!
quelle