Bahasa Indonesia

Alat pengembang · SHA kalkulator hash

Teks yang Sama, Berbeda SHA-256: Baris Baru, Pengkodean, dan Byte Tersembunyi

· Cara kerjanya

sha-256 pengkodean pemrosesan teks melakukan debug

Dua input teks yang tampak identik menghasilkan intisari SHA-256 berbeda, dengan baris baru tersembunyi dan byte pengkodean disorot
Ilustrasi vektor ToolAcre asli

Baris perintah mengatakan satu hal dan browser mengatakan hal lain untuk teks yang tampak sama. Di akhir baris baru, UTF-16 dan CRLF menjelaskan hampir setiap kasus; posting ini menunjukkan cara menemukan byte tersembunyi.

echo mengatakan satu hash, alat mengatakan yang lain — ketidakcocokan sehari-hari dan mengapa tidak ada yang salah

Terminal melaporkan satu intisari SHA-256 dan browser melaporkan yang lain untuk teks yang tampak identik. Alat baris perintah tidak rusak, dan browser juga tidak rusak. Byte yang di-hash tidak sama, meskipun karakter yang terlihat terlihat sama. Posting ini menelusuri sumber paling umum dari byte tersembunyi tersebut dan menunjukkan cara menemukannya dengan bidang teks dan penampil hex.

Masalahnya hampir tidak pernah terletak pada algoritma SHA-256 itu sendiri. SHA-256 bersifat deterministik: byte yang sama selalu menghasilkan intisari yang sama, dan intisarinya benar. Ketika output berbeda, byte berbeda. Kebingungan muncul karena "teks yang sama" bersifat ambigu: seseorang melihat karakter, tetapi fungsi hash melihat byte, dan terjemahan di antara karakter tersebut adalah tempat menyembunyikan perbedaan tersembunyi.

Baris baru di akhir — bagaimana echo menambahkan satu byte dan printf tidak, dan apa pengaruhnya terhadap intisari

Perintah echo di shell menambahkan karakter baris baru (U+000A, byte 0x0A) ke outputnya. Ini memang disengaja: konvensi di Unix bahwa file teks diakhiri dengan baris baru memberi echo satu pekerjaan sederhana. Saat Anda mengetik echo abc ke terminal dan menyalurkannya ke sha256sum, byte yang dicerna adalah 61 62 63 0A (kode ASCII untuk a, b, c, dan byte untuk baris baru), bukan 61 62 63. Alat yang ToolAcre gunakan untuk menghitung hash hash byte 61 62 63 dan menghasilkan hasil yang berbeda.

Perintah printf tidak menambahkan baris baru kecuali Anda menuliskannya ke dalam format string. printf abc | sha256sum menghitung intisari byte 61 62 63 saja, yang cocok dengan alat browser. Inilah sebabnya mengapa membandingkan hash sering kali berarti menjalankan printf alih-alih echo, atau menyalurkan ke sha256sum dengan flag -z, atau menentukan input mentah dalam bentuk apa pun yang disediakan alat Anda. Baris baru yang tersembunyi adalah satu-satunya alasan paling umum yang menyebabkan alat browser dan alat baris perintah tidak setuju.

UTF-8 versus UTF-16 — mengapa karakter yang sama memiliki byte yang berbeda di beberapa shell dan editor

UTF-8 dan UTF-16 mengkodekan karakter yang sama dengan urutan byte yang berbeda. Karakter é (U+00E9, e dengan aksen lancip) dikodekan sebagai dua UTF-8 byte: 0xC3 0xA9. Dalam UTF-16, yaitu bagaimana JavaScript merepresentasikan string secara internal, karakter yang sama menempati dua byte dalam urutan berbeda (tergantung pada endianness) atau bentuk yang berbeda seluruhnya jika disusun dari karakter dasar dan tanda gabungan. Saat Anda menyalin kafe dari aplikasi Windows dan menempelkannya ke alat hash browser, byte yang di-hash oleh alat tersebut mungkin tidak cocok dengan yang di-hash oleh terminal Mac, karena sistem defaultnya menggunakan pengkodean atau bentuk normalisasi yang berbeda.

Alat hash ToolAcre secara eksplisit mengonversi teks menjadi UTF-8 sebelum melakukan hashing melalui TextEncoder. Ini adalah pengkodean yang sama yang digunakan baris perintah Unix secara default. Kode sumber di apps/dev/src/lib/base64.js menunjukkan fungsi textToBytes yang memanggil TextEncoder().encode() baru, yang menjamin UTF-8. Jika sistem lain menggunakan UTF-16 atau Latin-1 atau pengkodean lainnya, byte yang dihasilkan akan berbeda. Alat ini menampilkan jumlah byte di samping intisari, itulah sebabnya menempelkan kafe dan membandingkan dengan hash baris perintah akan menunjukkan jumlah byte yang berbeda jika pengkodeannya berbeda.

CRLF, BOM dan normalisasi — akhiran baris, tanda urutan byte, dan aksen tersusun versus terurai sebagai perbedaan masukan yang tidak terlihat

CRLF (carriage return + line feed, bytes 0x0D 0x0A) adalah konvensi akhir baris di Windows; LF (line feed saja, byte 0x0A) adalah konvensi Unix. File teks yang terlihat identik ketika dibuka di editor teks dapat membawa akhiran baris yang berbeda, dan byte tersebut adalah bagian dari masukan ke hash. File yang diedit di Windows dan diperiksa dengan SHA-256 yang dihitung pada sistem Unix tidak akan cocok jika satu sistem telah mengonversi akhiran baris dan sistem lainnya belum.

Tanda urutan byte (BOM, bytes 0xEF 0xBB 0xBF untuk UTF-8) adalah urutan opsional di awal file yang menandakan pengkodean. Beberapa editor menambahkannya; beberapa alat mengupasnya; beberapa mengabaikannya. Jika sebuah file membawa BOM dan Anda melakukan hashing byte demi byte, BOM byte adalah bagian dari intisari. Jika Anda kemudian menyalin teks yang terlihat (dari mana pemirsa menyembunyikan BOM) ke alat yang tidak menambahkan BOM, intisarinya tidak akan cocok. Bentuk normalisasi teks (NFD versus NFC untuk aksen tersusun dan terurai) menambahkan lapisan lain: huruf beraksen yang sama dapat direpresentasikan sebagai karakter tunggal yang telah disusun sebelumnya atau sebagai karakter dasar diikuti dengan aksen gabungan, dan urutan byte berbeda.

Contoh praktis - satu string di-hash dengan dan tanpa baris baru, lalu dalam dua pengkodean, dengan setiap perbedaan byte ditampilkan

Metode diagnostik pertama: gunakan alat hex dump atau konverter online untuk melihat dengan tepat byte apa yang digunakan alat Anda. Tempelkan teks ke dalam encoder base64, enkodekan, dan Anda memiliki catatan tekstual byte. Kemudian dekode base64 pada baris perintah dengan base64 -d dan kirimkan ke od -A x -t x1z untuk melihat urutan byte hex. Jika byte cocok, algoritmanya benar; jika tidak, perbedaannya akan terlihat.

Metode diagnostik kedua: gunakan kalkulator hash ToolAcre SHA untuk melakukan hash pada input yang semakin panjang, dimulai dengan satu karakter. Tambahkan baris baru (yang berarti mengetikkan Enter di dalam kotak teks), menambahkan spasi, menambahkan teks yang sama dengan urutan escape UTF-16 jika input berasal dari sumber non-ASCII. Perhatikan perubahan intisari dengan setiap penambahan. Jumlah byte yang ditampilkan di samping intisari memberi tahu Anda berapa banyak byte yang di-hash oleh alat, sehingga mempersempit pencarian secara dramatis.

Kotak hex dan spasi putih pada keluarannya — perbedaannya hanya bersifat kosmetik

Representasi heksadesimal dari intisari tidak membedakan huruf besar dan kecil. Huruf besar dan kecil keduanya mewakili byte yang sama: A = 10, a = 10. Beberapa alat mengeluarkan huruf besar, beberapa menggunakan huruf kecil, beberapa juga mengizinkan. Jika satu intisari menggunakan huruf kecil dan inti lainnya menggunakan huruf besar, maka intisarinya sama. Spasi kosong pada tampilan ringkasan hanyalah tampilan kosmetik. Intisari yang ditampilkan sebagai ba78 16bf versus ba7816bf adalah sama; spasi hanyalah pilihan pemformatan. Ketidakcocokan yang disebabkan oleh huruf besar/kecil atau spasi bukanlah ketidakcocokan yang sebenarnya.

Perbedaan pemformatan dengan lebar tetap juga tidak terlihat pada tingkat byte. Intisari yang ditampilkan dengan tanda hubung, spasi, atau titik dua (seperti ba-78-16-bf) adalah konvensi pemformatan yang memudahkan manusia untuk membaca, bukan mengubah byte sebenarnya. Alat ToolAcre selalu mengeluarkan huruf kecil tanpa pemisah, yang merupakan format yang dicetak sebagian besar alat baris perintah. Jika Anda membandingkan dengan alat yang mengeluarkan emisi berbeda, konversikan ke representasi yang sama terlebih dahulu.

Apa yang tidak tercakup dalam hal ini — hashing file, di mana prinsip yang sama berlaku tetapi byte berasal dari disk dan bukan dari kolom teks

Kalkulator hash ToolAcre SHA melakukan konversi UTF-8 sebelum hashing, menampilkan jumlah byte masukan, dan menawarkan bentuk keluaran base64 dan heksadesimal. File sumber apps/dev/src/lib/hash.js menunjukkan fungsi hashText yang memanggil digestBytes, yang meneruskan bytes.slice().buffer ke crypto.subtle.digest. Komentar dalam file tersebut secara eksplisit mendokumentasikan bahwa langkah UTF-8 disengaja dan mencatat perbedaan antara pengkodean yang berbeda. Menguji masukan Anda terhadap vektor yang diketahui (hash abc hingga ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad dalam hex) menetapkan bahwa alat browser berfungsi dengan benar; setiap penyimpangan menunjukkan perbedaan byte dalam input.

Hashing file mengikuti prinsip yang sama. Yang penting adalah byte dalam file: perbedaan akhir baris saat Anda mengekspor dari satu sistem dan mengimpor ke sistem lain dapat mengubah setiap intisari. Beberapa alat menawarkan opsi untuk menangani akhiran baris selama perbandingan; yang lain meng-hash file apa adanya. Mengetahui apakah alat Anda meng-hash file sebagai biner atau melakukan normalisasi teks terlebih dahulu sangat penting agar dapat direproduksi.

Kesimpulan: byte hash, bukan teks — kalkulator hash ToolAcre SHA akan meng-hash byte yang Anda tempel, jadi periksa apa yang Anda tempelkan terlebih dahulu

Perbandingan dan verifikasi hanya berfungsi jika Anda melakukan hash pada byte yang sama. Mulailah dengan mengonfirmasi bahwa Anda melakukan hashing pada input yang sama persis: jalankan echo -n (atau printf) alih-alih echo untuk menghindari baris baru, tentukan pengkodean UTF-8 secara eksplisit jika alat Anda mengizinkannya, periksa apakah CRLF belum dimasukkan oleh editor atau utilitas sistem. Kemudian hash dengan kalkulator ToolAcre dan alat baris perintah secara berdampingan. Jika intisarinya cocok, byte-bytenya identik. Jika tidak, gunakan tampilan jumlah byte dan metode hex dump untuk menemukan perbedaan tersembunyi.

Setelah Anda memahami letak byte yang menyimpang, Anda dapat memilih apakah akan menormalkannya untuk perbandingan. Beberapa checksum dimaksudkan untuk memverifikasi integritas file persis seperti yang ada di disk, dalam hal ini hashing byte demi byte adalah tujuannya. Lainnya dimaksudkan untuk memverifikasi bahwa konten yang terlihat adalah sama, dalam hal ini normalisasi akhiran baris dan pengkodean sudah benar. Tidak ada yang salah; mereka menjawab pertanyaan yang berbeda. Algoritme SHA-256 selalu benar; pertanyaannya hanya apakah Anda memintanya untuk meng-hash input yang sama dalam kedua kasus.