Apakah ada cara enkripsi yang dapat mengambil string dengan panjang berapa pun dan menghasilkan hash sub-10 karakter? Saya ingin menghasilkan ID yang cukup unik tetapi berdasarkan isi pesan, bukan secara acak.
Saya bisa hidup dengan membatasi pesan ke nilai integer, jika string dengan panjang arbitrer tidak mungkin. Namun, hash tidak boleh sama untuk dua bilangan bulat yang berurutan, dalam hal ini.
encryption
uniqueidentifier
rath3r
sumber
sumber
Jawaban:
Anda dapat menggunakan algoritma hash yang tersedia secara umum (mis. SHA-1), yang akan memberi Anda hasil yang sedikit lebih panjang dari yang Anda butuhkan. Cukup potong hasilnya ke panjang yang diinginkan, yang mungkin cukup bagus.
Misalnya, dengan Python:
sumber
hash(a)
bertabrakan denganhash(b)
makabase64(hash(a))
juga bertabrakan denganbase64(hash(b))
.sha1
bertabrakan tetapi ini adalah cerita lain). Jika Anda memiliki hash 10 karakter, Anda mendapatkan entropi yang lebih tinggi jika dikodekan denganbase64
vsbase16
(atau hex). Seberapa tinggi? Denganbase16
Anda mendapatkan 4 bit informasi per karakter, denganbase64
angka ini 6bits / char. Totaly 10 char "hex" hash akan memiliki 40bits entropy sedangkan base64 60bits. Jadi agak lebih tahan, maaf kalau saya kurang super jernih.Jika Anda tidak memerlukan algoritme yang kuat terhadap modifikasi yang disengaja, saya telah menemukan algoritme yang disebut adler32 yang menghasilkan hasil yang cukup pendek (~ 8 karakter). Pilih dari tarik-turun di sini untuk mencobanya:
http://www.sha1-online.com/
sumber
Anda perlu mencirikan konten untuk menghasilkan intisari. Ada banyak hash yang tersedia tetapi 10 karakter cukup kecil untuk kumpulan hasil. Sebelumnya, orang menggunakan CRC-32, yang menghasilkan hash 33-bit (pada dasarnya 4 karakter ditambah satu bit). Ada juga CRC-64 yang menghasilkan hash 65-bit. MD5, yang menghasilkan hash 128-bit (16 byte / karakter) dianggap rusak untuk tujuan kriptografi karena dua pesan dapat ditemukan yang memiliki hash yang sama. Tidak perlu dikatakan lagi bahwa setiap kali Anda membuat intisari 16-byte dari pesan dengan panjang acak, Anda akan mendapatkan duplikat. Semakin pendek cerna, semakin besar risiko tabrakan.
Namun, kekhawatiran Anda bahwa hash tidak sama untuk dua pesan yang berurutan (baik bilangan bulat maupun tidak) harus benar dengan semua hash. Bahkan sedikit perubahan dalam pesan asli akan menghasilkan hasil intisari yang sangat berbeda.
Jadi, menggunakan sesuatu seperti CRC-64 (dan mendasarkan hasilnya) akan membawa Anda ke lingkungan yang Anda cari.
sumber
Hanya meringkas jawaban yang bermanfaat bagi saya (mencatat komentar @erasmospunk tentang penggunaan encoding base-64). Tujuan saya adalah memiliki tali pendek yang sebagian besar unik ...
Saya bukan ahli, jadi perbaiki ini jika ada kesalahan yang mencolok (dengan Python lagi seperti jawaban yang diterima):
Di
result
sini menggunakan lebih dari sekedar karakter hex (apa yang akan Anda dapatkan jika Anda gunakanhash.hexdigest()
) sehingga kecil kemungkinannya untuk bertabrakan (yaitu, harus lebih aman untuk dipotong daripada hex digest).Catatan: Menggunakan UUID4 (acak). Lihat http://en.wikipedia.org/wiki/Universally_unique_identifier untuk jenis lainnya.
sumber
Anda dapat menggunakan algoritme hash yang ada yang menghasilkan sesuatu yang pendek, seperti MD5 (128 bit) atau SHA1 (160). Kemudian Anda dapat mempersingkatnya lebih lanjut dengan XORing bagian intisari dengan bagian lain. Ini akan meningkatkan kemungkinan tabrakan, tetapi tidak seburuk hanya memotong digest.
Juga, Anda bisa memasukkan panjang data asli sebagai bagian dari hasil untuk membuatnya lebih unik. Misalnya, XORing paruh pertama intisari MD5 dengan paruh kedua akan menghasilkan 64 bit. Tambahkan 32 bit untuk panjang data (atau lebih rendah jika Anda tahu bahwa panjang akan selalu sesuai dengan bit yang lebih sedikit). Itu akan menghasilkan hasil 96-bit (12-byte) yang kemudian bisa Anda ubah menjadi string hex 24 karakter. Bergantian, Anda dapat menggunakan pengkodean basis 64 untuk membuatnya lebih pendek.
sumber
Jika perlu,
"sub-10-character hash"
Anda dapat menggunakan algoritma Fletcher-32 yang menghasilkan hash 8 karakter (32 bit), CRC-32 atau Adler-32 .CRC-32 lebih lambat dari Adler32 dengan faktor 20% - 100%.
Fletcher-32 sedikit lebih andal dibandingkan Adler-32. Ini memiliki biaya komputasi yang lebih rendah daripada checksum Adler: perbandingan Fletcher vs Adler .
Program contoh dengan beberapa implementasi Fletcher diberikan di bawah ini:
Keluaran:
Setuju dengan vektor Uji :
Adler-32 memiliki kelemahan untuk pesan singkat dengan beberapa ratus byte, karena checksum untuk pesan ini memiliki cakupan yang buruk dari 32 bit yang tersedia. Periksa ini:
Algoritme Adler32 tidak cukup rumit untuk bersaing dengan checksum yang sebanding .
sumber
Cukup jalankan ini di terminal (di MacOS atau Linux):
8 karakter.
sumber
Anda dapat menggunakan pustaka hashlib untuk Python. The shake_128 dan shake_256 algoritma memberikan hash panjang variabel. Berikut beberapa kode yang berfungsi (Python3):
Perhatikan bahwa dengan parameter panjang x (misalnya 5) fungsi mengembalikan nilai hash dengan panjang 2x .
sumber
Sekarang tahun 2019 dan ada opsi yang lebih baik. Yakni, xxhash .
sumber
Saya membutuhkan sesuatu di sepanjang garis fungsi pengurangan string sederhana baru-baru ini. Pada dasarnya, kodenya terlihat seperti ini (kode C / C ++ di depan):
Ini mungkin memiliki lebih banyak tabrakan daripada yang diinginkan tetapi tidak dimaksudkan untuk digunakan sebagai fungsi hash kriptografi. Anda dapat mencoba berbagai pengali (yaitu mengubah 37 ke bilangan prima lain) jika Anda mendapatkan terlalu banyak tabrakan. Salah satu fitur menarik dari potongan ini adalah ketika Src lebih pendek dari Dest, Dest berakhir dengan string input apa adanya (0 * 37 + nilai = nilai). Jika Anda menginginkan sesuatu yang "dapat dibaca" di akhir proses, Normalisasi akan menyesuaikan byte yang diubah dengan biaya meningkatkan tabrakan.
Sumber:
https://github.com/cubiclesoft/cross-platform-cpp/blob/master/sync/sync_util.cpp
sumber
DestSize
lebih dari 4 (32 bit) ketika hash itu sendiri sangat jelek? Jika Anda menginginkan resistensi tabrakan yang disediakan oleh keluaran yang lebih besar dari int, Anda akan menggunakan SHA.