1# Copyright (c) 2003-2016 CORE Security Technologies 2# 3# This software is provided under under a slightly modified version 4# of the Apache Software License. See the accompanying LICENSE file 5# for more information. 6# 7# Description: 8# Generate UUID compliant with http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt. 9# A different, much simpler (not necessarily better) algorithm is used. 10# 11# Author: 12# Javier Kohen (jkohen) 13# 14 15import re 16 17from random import randrange 18from struct import pack, unpack 19 20try: 21 long # Python 2 22except NameError: 23 long = int # Python 3 24 25def generate(): 26 # UHm... crappy Python has an maximum integer of 2**31-1. 27 top = (1<<31)-1 28 return pack("IIII", randrange(top), randrange(top), randrange(top), randrange(top)) 29 30def bin_to_string(uuid): 31 uuid1, uuid2, uuid3 = unpack('<LHH', uuid[:8]) 32 uuid4, uuid5, uuid6 = unpack('>HHL', uuid[8:16]) 33 return '%08X-%04X-%04X-%04X-%04X%08X' % (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) 34 35def string_to_bin(uuid): 36 matches = re.match('([\dA-Fa-f]{8})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})-([\dA-Fa-f]{4})([\dA-Fa-f]{8})', uuid) 37 (uuid1, uuid2, uuid3, uuid4, uuid5, uuid6) = map(lambda x: long(x, 16), matches.groups()) 38 uuid = pack('<LHH', uuid1, uuid2, uuid3) 39 uuid += pack('>HHL', uuid4, uuid5, uuid6) 40 return uuid 41 42def stringver_to_bin(s): 43 (maj,min) = s.split('.') 44 return pack('<H',int(maj)) + pack('<H',int(min)) 45 46def uuidtup_to_bin(tup): 47 if len(tup) != 2: return 48 return string_to_bin(tup[0]) + stringver_to_bin(tup[1]) 49 50def bin_to_uuidtup(bin): 51 assert len(bin) == 20 52 uuidstr = bin_to_string(bin[:16]) 53 maj, min = unpack("<HH", bin[16:]) 54 return uuidstr, "%d.%d" % (maj, min) 55 56#input: string 57#output: tuple (uuid,version) 58#if version is not found in the input string "1.0" is returned 59#example: 60# "00000000-0000-0000-0000-000000000000 3.0" returns ('00000000-0000-0000-0000-000000000000','3.0') 61# "10000000-2000-3000-4000-500000000000 version 3.0" returns ('00000000-0000-0000-0000-000000000000','3.0') 62# "10000000-2000-3000-4000-500000000000 v 3.0" returns ('00000000-0000-0000-0000-000000000000','3.0') 63# "10000000-2000-3000-4000-500000000000" returns ('00000000-0000-0000-0000-000000000000','1.0') 64def string_to_uuidtup(s): 65 g = re.search("([A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}).*?([0-9]{1,5}\.[0-9]{1,5})",s+" 1.0") 66 if g: 67 (u,v) = g.groups() 68 return (u,v) 69 return 70 71def uuidtup_to_string(tup): 72 uuid, (maj, min) = tup 73 return "%s v%d.%d" % (uuid, maj, min) 74