J'essaye de hacher une chaîne en utilisant SHA256, j'utilise le code suivant:
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;
}
}
Cependant, ce code donne des résultats significativement différents par rapport à mes amis php, ainsi que des générateurs en ligne (tels que Ce générateur )
Quelqu'un sait-il quelle est l'erreur? Différentes bases?
Réponses:
Encoding.Unicode
est le nom trompeur de Microsoft pour UTF-16 (un encodage double largeur, utilisé dans le monde Windows pour des raisons historiques mais non utilisé par personne d'autre). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspxSi vous inspectez votre
bytes
tableau, vous verrez que chaque octet sur deux est0x00
(à cause du codage double largeur).Vous devriez utiliser à la
Encoding.UTF8.GetBytes
place.Mais aussi, vous verrez des résultats différents selon que vous considérez ou non l'
'\0'
octet de fin comme faisant partie des données que vous hachez. Le hachage des deux octets"Hi"
donnera un résultat différent du hachage des trois octets"Hi"
. Vous devrez décider ce que vous voulez faire. (Vous voulez probablement faire ce que fait le code PHP de votre ami.)Pour le texte ASCII,
Encoding.UTF8
conviendra certainement. Si vous visez une compatibilité parfaite avec le code de votre ami, même sur des entrées non ASCII, vous feriez mieux d'essayer quelques cas de test avec des caractères non ASCII tels queé
et家
et voir si vos résultats correspondent toujours. Sinon, vous devrez comprendre quel encodage votre ami utilise réellement; il peut s'agir de l'une des «pages de codes» 8 bits qui étaient populaires avant l'invention d'Unicode. (Encore une fois, je pense que Windows est la principale raison pour laquelle quiconque doit encore s'inquiéter des "pages de codes".)la source
short
s encodés en UTF16 ", mais pas le "tri par octets encodés en UTF16", sauf si vous êtes sur un système big-endian, ce que Windows n'est pas.) Cependant, le "tri" en Unicode est en fait un sujet compliqué qui devrait être conservé pour un autre jour.J'ai aussi eu ce problème avec un autre style d'implémentation mais j'ai oublié d'où je l'ai eu puisqu'il y a 2 ans.
Lorsque j'entre quelque chose comme
abcdefghi2013
pour une raison quelconque, cela donne des résultats différents et entraîne des erreurs dans mon module de connexion. Ensuite, j'ai essayé de modifier le code de la même manière que suggéré par Quuxplusone et j'ai changé l'encodage deASCII
àUTF8
puis cela a finalement fonctionné!Merci encore Quuxplusone pour la réponse merveilleuse et détaillée! :)
la source
hash += bit.ToString("x2");
que j'ai une question ici: j'utilisaisConvert.ToBase64String(byte[] encryptedBytes)
pour convertir des octets en chaîne. cela me donnait un résultat différent. alors quelle est la différence entre ces deux méthodes de conversion d'octets en chaîne ..?La raison pour laquelle vous obtenez des résultats différents est que vous n'utilisez pas le même codage de chaîne. Le lien que vous avez mis pour le site Web en ligne qui calcule SHA256 utilise le codage UTF8, alors que dans votre exemple vous avez utilisé le codage Unicode. Ce sont deux encodages différents, vous n'obtenez donc pas le même résultat. Avec l'exemple ci-dessus, vous obtenez le même hachage SHA256 du site Web lié. Vous devez utiliser le même encodage également en PHP.
Le minimum absolu que tout développeur de logiciel doit absolument et positivement savoir sur l'Unicode et les jeux de caractères (sans excuses!)
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/
la source
Dans la version PHP, vous pouvez envoyer «true» dans le dernier paramètre, mais la valeur par défaut est «false». L'algorithme suivant est équivalent à la fonction de hachage PHP par défaut lors du passage de 'sha256' comme premier paramètre:
la source
ASCII
et ne le ferais pas à labyte[] arrBytes = System.Text.Encoding.UTF8.GetBytes(strData)
place.la source
Le moyen le plus court et le plus rapide jamais conçu. Seulement 1 ligne!
la source
Cela fonctionne pour moi dans .NET Core 3.1.
Mais pas dans l'aperçu de .NET 5 7.
la source