Saya mencoba untuk hash string menggunakan SHA256, saya menggunakan kode berikut:
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;
}
}
Namun, kode ini memberikan hasil yang sangat berbeda dibandingkan dengan teman saya php, serta generator online (seperti generator ini )
Adakah yang tahu apa kesalahannya? Basis yang berbeda?
Jawaban:
Encoding.Unicode
adalah nama menyesatkan Microsoft untuk UTF-16 (pengodean lebar-ganda, digunakan di dunia Windows untuk alasan historis tetapi tidak digunakan oleh orang lain). http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspxJika Anda memeriksa
bytes
array Anda, Anda akan melihat bahwa setiap byte kedua adalah0x00
(karena pengodean lebar-ganda).Anda seharusnya menggunakan
Encoding.UTF8.GetBytes
.Tetapi juga, Anda akan melihat hasil yang berbeda tergantung pada apakah Anda menganggap
'\0'
byte terminating menjadi bagian dari data yang Anda hashing. Hashing dua byte"Hi"
akan memberikan hasil yang berbeda dari hashing tiga byte"Hi"
. Anda harus memutuskan mana yang ingin Anda lakukan. (Mungkin Anda ingin melakukan yang mana saja salah satu kode PHP teman Anda lakukan.)Untuk teks ASCII,
Encoding.UTF8
pasti akan cocok. Jika Anda bertujuan untuk kompatibilitas sempurna dengan kode teman Anda, bahkan pada input non-ASCII, Anda sebaiknya mencoba beberapa kasus uji dengan karakter non-ASCII sepertié
dan家
dan melihat apakah hasil Anda masih cocok. Jika tidak, Anda harus mencari tahu apa pengkodean yang benar-benar digunakan teman Anda; itu mungkin salah satu dari "halaman kode" 8-bit yang dulu populer sebelum penemuan Unicode. (Sekali lagi, saya pikir Windows adalah alasan utama bahwa siapa pun masih perlu khawatir tentang "halaman kode".)sumber
short
", tetapi tidak "menyortir oleh UTF16-disandikan byte" kecuali Anda berada di sistem big-endian, yang Windows tidak.) Namun, "menyortir" di Unicode benar-benar sebuah topik rumit yang harus disimpan untuk hari lain.Saya juga punya masalah dengan gaya implementasi yang lain, tetapi saya lupa di mana saya mendapatkannya sejak 2 tahun yang lalu.
Ketika saya memasukkan sesuatu seperti
abcdefghi2013
karena suatu alasan itu memberikan hasil dan hasil yang berbeda dalam kesalahan dalam modul login saya. Kemudian saya mencoba memodifikasi kode dengan cara yang sama seperti yang disarankan oleh Quuxplusone dan mengubah pengkodean dariASCII
keUTF8
maka akhirnya bekerja!Terima kasih lagi Quuxplusone untuk jawaban yang indah dan terperinci! :)
sumber
hash += bit.ToString("x2");
saya punya pertanyaan di sini: Saya menggunakanConvert.ToBase64String(byte[] encryptedBytes)
untuk mengkonversi kembali dari byte ke string. itu memberi saya hasil yang berbeda. jadi apa perbedaan antara kedua metode konversi dari byte ke string ..?Alasan mengapa Anda mendapatkan hasil yang berbeda adalah karena Anda tidak menggunakan pengkodean string yang sama. Tautan yang Anda masukkan untuk situs web online yang menghitung SHA256 menggunakan Pengkodean UTF8, sedangkan dalam contoh Anda, Anda menggunakan Pengodean Unicode. Mereka adalah dua pengkodean yang berbeda, sehingga Anda tidak mendapatkan hasil yang sama. Dengan contoh di atas Anda mendapatkan hash SHA256 yang sama dari situs web tertaut. Anda perlu menggunakan penyandian yang sama juga di PHP.
Minimum Mutlak Setiap Pengembang Perangkat Lunak, Sepenuhnya Pasti Harus Tahu Tentang Unicode dan Karakter (Tidak Ada Alasan!)
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positive-must-know-about-unicode-and-character-sets-no-excuses/
sumber
Dalam versi PHP Anda dapat mengirim 'true' di parameter terakhir, tetapi defaultnya adalah 'false'. Algoritme berikut ini setara dengan fungsi hash PHP default saat meneruskan 'sha256' sebagai parameter pertama:
sumber
ASCII
dan melakukanbyte[] arrBytes = System.Text.Encoding.UTF8.GetBytes(strData)
sebaliknya.sumber
Cara terpendek dan tercepat yang pernah ada. Hanya 1 baris!
sumber