可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Ok I am trying to write a basic converter of a string to md5 hash code but when I run my program I keep getting an error that say's:
Traceback (most recent call last): File "C:\Users\Shane\Documents\Amer CISC\lab4.py", line 30, in <module> assertEqual (computeMD5hash("The quick brown fox jumps over the lazy dog"),("9e107d9d372bb6826bd81d3542a419d6")) File "C:\Users\Shane\Documents\Amer CISC\lab4.py", line 27, in computeMD5hash m.update(string) TypeError: Unicode-objects must be encoded before hashing
My code looks like this:
def computeMD5hash(string): import hashlib from hashlib import md5 m = hashlib.md5() m.update((string)) md5string=m.digest() return md5string
回答1:
As the error suggests, your string must be unicode and you have to encode it. Looking at the call you make (from your stack trace):
computeMD5hash("The quick brown fox jumps over the lazy dog")
it looks like you must be running Python 3 where strings are unicode objects. To encode to a byte representation which can then be processed by the hashlib, change this
m.update((string))
to this (if utf-8 is an appropriate encoding for you to use - it depends how you will be using this):
m.update(string.encode('utf-8'))
If this is all news to you, you should probably read the excellent Python 3 Unicode HOWTO.
Also, while I'm here, your code has some other issues
- some unecessary bits - no need for the
from hashlib import line or the temporary md5string. - it's bad form to import modules from within a function, so
import hashlib should be moved to module scope. - the function is returning the
digest() which is raw binary, and from your stack trace it looks like you're expecting the hexdigest() instead which is the same thing represented as a hexadecimal string.
To fix and tidy it all up, try this:
import hashlib def computeMD5hash(my_string): m = hashlib.md5() m.update(my_string.encode('utf-8')) return m.hexdigest()
回答2:
Rather than trying to hash the string, you should hash an encoded byte sequence. Instead of
>>> import hashlib >>> hashlib.md5("fred") Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Unicode-objects must be encoded before hashing
you should encode it, e.g.:
>>> "fred".encode("utf") b'fred' >>> hashlib.md5("fred".encode("utf")).hexdigest() '570a90bfbf8c7eab5dc5d4e26832d5b1'
In Python 2 you could get away without doing this, and it led to no end of unnoticed bugs. Fortunately Python 3 has much saner unicode support, and distinguishes between bytes and strings.
回答3:
回答4:
!/usr/bin/env python
coding=utf-8
import sys, os, stat import pygtk, gtk import zbarpygtk import pycurl from time import strftime, localtime import pango
class qrdat:
def __init__(self): """ VARIABLES DE CONFIGURACION """ # Prefijo para el nombre de los archivos de registros prefijo = 'Registro' # Lugar de almacenamiento de archivos de registros # Por defecto se guarda en la carpeta personal del usuario directorio = os.getenv('HOME') # Descomentar la siguiente linea y digitar la ruta de la carpeta # donde se guardaran los archivos #directorio = '/home/olpc/Escritorio' # Modo de reproduccion de sonido: # 1 : sonido enviado directamente a la tarjeta de sonido # 2 : sonido de alerta del sistema self.beep_mode = 1 # No modificar abajo self.open_file = None self.video_device = '/dev/video0' self.fecha = strftime("%Y-%m-%d",localtime()) self.filename = directorio+'/'+prefijo+'-'+self.fecha+'.csv' if len(sys.argv) > 1: self.video_device = sys.argv[1] def decoded(self, zbar, data): """funcion invocada cuando un codigo es decodificado por el control zbar. """ datos = data.split(':') qrdata = datos[1] # guardar datos self.save(qrdata) # sonido de recepcion self.beep(self.beep_mode) # mostrar datos buf = self.results.props.buffer end = buf.get_end_iter() buf.insert(end, self.hora()+' - '+qrdata+"\n") self.results.scroll_to_iter(end, 0) def show(self): """Funcion que crea muestra la ventana principal """ # threads *must* be properly initialized to use zbarpygtk gtk.gdk.threads_init() gtk.gdk.threads_enter() window = gtk.Window() window.set_title("Control de Asistencia QR") window.set_border_width(8) window.connect("destroy", gtk.main_quit) # zbar self.zbar = zbarpygtk.Gtk() self.zbar.connect("decoded-text", self.decoded) self.video_device = '/dev/video0' self.zbar.connect("notify::video-enabled", self.video_enabled) self.zbar.connect("notify::video-opened", self.video_opened) self.zbar.set_video_device(self.video_device) # combine combo box and buttons horizontally hbox = gtk.HBox(spacing=8) # text box for holding results self.results = gtk.TextView() self.results.set_size_request(320, 128) self.results.props.editable = self.results.props.cursor_visible = False self.results.modify_font(pango.FontDescription("monospace 12")) self.results.set_left_margin(4) # combine inputs, scanner, and results vertically vbox = gtk.VBox(spacing=8) vbox.pack_start(hbox, expand=False) vbox.pack_start(self.zbar) vbox.pack_start(self.results, expand=False) window.add(vbox) window.set_geometry_hints(self.zbar, min_width=320, min_height=240) window.show_all() def run(self): """Funcion que inicia el funcionamiento de la ventana""" gtk.main() gtk.gdk.threads_leave() def save(self,data): """ Funcion que guarda el archivo de registro """ f = open(self.filename,'a') f.write(self.fecha+','+self.hora()+','+data+'\n') f.close() def hora(self): """ Funcion que obtiene la hora local """ return strftime("%H:%M:%S",localtime()) def beep(self, beep_mode): if os.access('/dev/audio', os.W_OK ) and beep_mode == 1: """ Genera un sonido enviado a la tarjeta de sonido""" frequency = 100 amplitude = 200 duration = 2 sample = 8000 half_period = int(sample/frequency/2) beep = chr(amplitude)*half_period+chr(0)*half_period beep *= int(duration*frequency) audio = file('/dev/audio', 'wb') audio.write(beep) audio.close() else: """ Reproduce sonido del propio sistema """ f=open('/dev/tty','w') f.write(chr(7)) f.close() def video_enabled(self, zbar, param): """callback invoked when the zbar widget enables or disables video streaming. updates the status button state to reflect the current video state """ enabled = zbar.get_video_enabled() def video_opened(self, zbar, param): """callback invoked when the zbar widget opens or closes a video device. also called when a device is closed due to error. updates the status button state to reflect the current video state """ opened = zbar.get_video_opened() def video_changed(self, widget): """callback invoked when a new video device is selected from the drop-down list. sets the new device for the zbar widget, which will eventually cause it to be opened and enabled """ dev = self.video_list.get_active_text() if dev[0] == '<': dev = '' self.zbar.set_video_device(dev)
if name == "main":
qr = qrdat() qr.show() qr.run()