แฮชแบบสุ่มใน Python


104

เป็นอะไรที่ง่ายที่สุดวิธีการสร้างกัญชาสุ่ม (MD5) ในงูใหญ่?


1
สุ่มในสิ่งใด? หรือสำหรับวัตถุ? หากคุณต้องการสุ่ม MD5 เพียงแค่เลือกตัวเลขบางตัว
samoz

ฉันกำลังเปลี่ยนชื่อไฟล์ก่อนที่จะอัปโหลดและต้องการชื่อไฟล์แบบนี้: timestamp_randommd5.extension Cheers!
mistero

5
คุณสามารถเปลี่ยนชื่อเป็น timestamp_randomnumber.ext ไม่มีเหตุผลจริงๆว่าทำไม md5 (randomnumber) จะดีไปกว่า randomnumber เอง

คำตอบที่ดีที่สุดสำหรับ Python 3 คือตัวสุดท้ายimport uuid; uuid.uuid().hex stackoverflow.com/a/20060712/3218806
maxbellec

คำตอบ:


136

md5-hash เป็นเพียงค่า 128 บิตดังนั้นหากคุณต้องการสุ่ม:

import random

hash = random.getrandbits(128)

print("hash value: %032x" % hash)

ฉันไม่เห็นประเด็นจริงๆ บางทีคุณควรอธิบายให้ละเอียดว่าทำไมคุณถึงต้องการสิ่งนี้ ...


+1 สำหรับการไม่คำนวณแฮชที่ค่อนข้างแพงจากตัวเลขสุ่ม: วิธีนี้เร็วกว่า 5 เท่า
Nicolas Dumazet

11
+1 - แน่นอนว่านี่ดีกว่าคำตอบของฉันสามารถใช้เช่นนี้ได้เช่นกัน: hex (random.getrandbits (128)) [2: -1] สิ่งนี้ให้ผลลัพธ์เหมือนกับวิธี md5 hexdigest
Jiri

1
การเรียก random.seed () ไม่มีประโยชน์ไม่มากก็น้อย
tzot

2
ฉันจะใช้ os.urandom เพราะต้องการแฮช MD5 อาจหมายถึงต้องการที่ปลอดภัย
ไม่ทราบ

9
วิธีดำเนินการos.urandomดังนี้''.join('%02x' % ord(x) for x in os.urandom(16))
FogleBird

106

ฉันคิดว่าสิ่งที่คุณกำลังมองหาคือตัวระบุที่ไม่ซ้ำกันจากนั้นโมดูล UUID ใน python คือสิ่งที่คุณกำลังมองหา

import uuid
uuid.uuid4().hex

UUID4 ให้ตัวระบุเฉพาะแบบสุ่มที่มีความยาวเท่ากับผลรวม md5 Hex จะแสดงเป็นสตริงฐานสิบหกแทนที่จะส่งคืนวัตถุ uuid

http://docs.python.org/2/library/uuid.html


49

มีการเพิ่มsecretsโมดูลใน Python 3.6+ ให้ค่าสุ่มที่ปลอดภัยด้วยการเข้ารหัสด้วยการโทรเพียงครั้งเดียว ฟังก์ชันใช้nbytesอาร์กิวเมนต์ทางเลือกค่าเริ่มต้นคือ 32 (ไบต์ * 8 บิต = โทเค็น 256 บิต) MD5 มีแฮช 128 บิตดังนั้นให้ 16 สำหรับโทเค็น "MD5-like"

>>> import secrets

>>> secrets.token_hex(nbytes=16)
'17adbcf543e851aa9216acc9d7206b96'

>>> secrets.token_urlsafe(16)
'X7NYIolv893DXLunTzeTIQ'

>>> secrets.token_bytes(128 // 8)
b'\x0b\xdcA\xc0.\x0e\x87\x9b`\x93\\Ev\x1a|u'

46

ใช้ได้กับทั้ง python 2.x และ 3.x

import os
import binascii
print(binascii.hexlify(os.urandom(16)))
'4a4d443679ed46f7514ad6dbe3733c3d'

2
วิธีการเข้ารหัสเลขฐานสิบหกนี้ใช้ไม่ได้ใน Python 3 อีกต่อไป
Caramdir

1
ขอบคุณ. นี่เป็นวิธีที่ดีที่สุดในการสร้างคีย์แฮชแบบสุ่ม
Jake

7
ใช้ได้กับ 2.x และ 3.x: binascii.hexlify (os.urandom (16))
Clay

20

อีกวิธีหนึ่ง คุณไม่ต้องจัดรูปแบบ int เพื่อรับ

import random
import string

def random_string(length):
    pool = string.letters + string.digits
    return ''.join(random.choice(pool) for i in xrange(length))

ให้ความยืดหยุ่นกับความยาวของสตริง

>>> random_string(64)
'XTgDkdxHK7seEbNDDUim9gUBFiheRLRgg7HyP18j6BZU5Sa7AXiCHP1NEIxuL2s0'

ฉันอาจจะเปลี่ยน string.letters เป็น 'abcdf' เพื่อสะท้อนเลขฐานสิบหก แต่ทางออกที่ดี!
ranchalp

''.join(random.sample(string.ascii_letters + string.digits, 8))pythonic มากขึ้น?
404pio

6

อีกแนวทางหนึ่งสำหรับคำถามเฉพาะนี้:

import random, string

def random_md5like_hash():
    available_chars= string.hexdigits[:16]
    return ''.join(
        random.choice(available_chars)
        for dummy in xrange(32))

ฉันไม่ได้บอกว่ามันเร็วกว่าหรือดีกว่าคำตอบอื่น แค่นั้นก็เป็นอีกแนวทางหนึ่ง :)




0
from hashlib import md5
plaintext = input('Enter the plaintext data to be hashed: ') # Must be a string, doesn't need to have utf-8 encoding
ciphertext = md5(plaintext.encode('utf-8').hexdigest())
print(ciphertext)

นอกจากนี้ควรสังเกตด้วยว่า MD5 เป็นฟังก์ชันแฮชที่อ่อนแอมากนอกจากนี้ยังพบการชนกัน (ค่าข้อความธรรมดาสองค่าที่แตกต่างกันส่งผลให้แฮชเดียวกัน) เพียงใช้ค่าสุ่มสำหรับplaintext.


การกำหนดให้ผู้ใช้ป้อนข้อมูลไม่ได้ช่วยในแง่มุมที่ "ง่ายที่สุด" ของคำถามเดิม ...
AS Mackay

คุณตรวจสอบรหัสของคุณหรือไม่ ไม่มี
วงเล็บ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.