rendered paste body# Copyright (c) 2006 Seo Sanghyeon# 2006-01-26 sanxiyn Created as md5.py# 2006-03-25 sanxiyn Copied md5.py as sha.py# 2006-10-11 sanxiyn Reorganized to follow hashlib API# Added digest_size# 2006-11-11 sanxiyn Accept array as well as string# 2008-04-28 sandra Fixed to work with Silverlight 2.0b1from System.Security import Cryptographyfrom System import Array, Bytedef to_bytes(string): return Array[Byte](map(ord, string))def to_string(bytes): return ''.join(map(chr, bytes))empty = Array[Byte]([])import arrayclass PythonHash: def __init__(self, context): self.context = context self.digest_size = context.HashSize / 8 self.is_digested = False # Silverlight 2.0b1 def update(self, string): if not self.is_digested: if isinstance(string, array.array): string = string.array if isinstance(string, str): bytes = to_bytes(string) elif isinstance(string, Array[Byte]): bytes = string elif isinstance(string, Array): bytes = Array[Byte](list(string)) else: raise TypeError("argument must be string or array") self.context.TransformBlock(bytes, 0, len(bytes), bytes, 0) else: raise NotImplementedError( 'Cannot call update() after digest() in this version of the .NET framework') def digest(self): try: context = self.context.MemberwiseClone() except: context = self.context if not self.is_digested: context.TransformFinalBlock(empty, 0, 0) self.is_digested = context is self.context return to_string(context.Hash) def hexdigest(self): return ''.join(['%02x' % ord(c) for c in self.digest()]) def copy(self): try: context = self.context.MemberwiseClone() except: raise NotImplementedError( 'copy() is not implemented for this version of the .NET framework') return PythonHash(context)# As of Mono 1.1.17.1, HashAlgorithm.Create doesn't accept lowercased# algorithm names unlike .NET. Mono bug #79641.def new(name, string=''): hash = None if hasattr(HashAlgorithm, 'Create'): name = name.upper() context = Cryptography.HashAlgorithm.Create(name) if context: hash = PythonHash(context) else: # Silverlight 2.0b1 name = name.lower() try: hash = globals()[name.lower()] except KeyError: pass if hash is None: raise ValueError('unsupported hash type') if string and isinstance(hash, PythonHash): hash.update(string) return hashdef make_new(name): algorithm = getattr(Cryptography, name) if hasattr(algorithm, 'Create'): factory = algorithm.Create else: # Silverlight 2.0b1 factory = getattr(Cryptography, name + 'Managed') def new(string=''): hash = PythonHash(factory()) if string: hash.update(string) return hash return newfor algo in ('MD5', 'SHA1', 'SHA224', 'SHA256', 'SHA384', 'SHA512'): if hasattr(Cryptography, algo): hash = make_new(algo) else: def not_available(string=''): raise NotImplementedError( ".NET Framework doesn't provide %s hash algorithm" % algo) hash = not_available globals()[algo.lower()] = hashtry: import clr clr.AddReference('Mono.Security')except: passelse: # Use Mono's SHA224 implementation when available from Mono.Security.Cryptography import SHA224 sha224 = make_new(SHA224)