class UUIDParseFailureKind: FORMAT = 2 class UUIDParseNumbers: NOSPACE = 2 class UUIDParseResult: def __init__(self): self.parsedGuid = Guid() self.kind = None self.message = None def setFailure(kind, message): self.kind = kind self.message = message class Guid: __urand = None def __init__(self, val : str = None): if Guid.__urand is None: Guid.__urand = open("/dev/urandom", "rb") self.value = val self.__a = 0 self.__b = 0 self.__c = 0 self.__d = 0 self.__e = 0 self.__f = 0 self.__g = 0 self.__h = 0 self.__i = 0 self.__j = 0 self.__k = 0 @staticmethod def __stringToInt(guidString : str, parsePos : int, requiredLength : int, flags : int, result : int, parseResult): parseWhat = guidString[parsePos:(parsePos+requiredLength)] result = int(parseWhat, 16) parsePos += requiredLength return (parsePos, result) @staticmethod def __tryParseGuidWithDashes(guidString : str) -> UUIDParseResult: startPos = 0 temp = 0 templ = 0 currentPos = 0 result = UUIDParseResult() hasDashes = True # check to see that it's the proper length if guidString[0] == '{': if len(guidString) != 38 or guidString[37] != '}': result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[{38]") return result startPos = 1 elif guidString[0] == '(': if len(guidString) != 38 or guidString[37] != ')': result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[(38]") return result startPos = 1 elif len(guidString) != 36: if len(guidString) != 32: result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidInvLen[36]") return result else: hasDashes = False if hasDashes: if (guidString[8 + startPos] != '-' or guidString[13 + startPos] != '-' or guidString[18 + startPos] != '-' or guidString[23 + startPos] != '-'): result.setFailure(UUIDParseFailureKind.FORMAT, "Format_GuidDashes") return result currentPos = startPos (parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 8, UUIDParseNumbers.NOSPACE, temp, result) result.parsedGuid.__a = temp currentPos = parsePos if hasDashes: currentPos = currentPos + 1; # Increment past the '-'; (parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result) result.parsedGuid.__b = temp currentPos = parsePos if hasDashes: currentPos = currentPos + 1 # Increment past the '-'; (parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result) result.parsedGuid.__c = temp currentPos = parsePos if hasDashes: currentPos = currentPos + 1 # Increment past the '-'; (parsePos, temp) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, temp, result) result.parsedGuid.__d = temp >> 8 result.parsedGuid.__e = temp currentPos = parsePos if hasDashes: currentPos = currentPos + 1 # Increment past the '-'; startPos = currentPos (parsePos, templ) = Guid.__stringToInt(guidString, currentPos, 8, UUIDParseNumbers.NOSPACE, templ, result) currentPos = parsePos (parsePos, temp2) = Guid.__stringToInt(guidString, currentPos, 4, UUIDParseNumbers.NOSPACE, templ, result) # /* # if ($currentPos - $startPos != 12) { # $result->setFailure(UUIDParseFailureKind::FORMAT, "Format_GuidInvLen(*)") # return $result; # } # */ result.parsedGuid.__j = temp2 >> 8 result.parsedGuid.__k = temp2 temp = templ result.parsedGuid.__f = temp >> 24 result.parsedGuid.__g = temp >> 16 result.parsedGuid.__h = temp >> 8 result.parsedGuid.__i = temp return result def parse(value : str): if value is None: return None result = Guid.__tryParseGuidWithDashes(value) return result.parsedGuid def __eq__(self, other): # /* # if ( # $uuid->clock_seq_hi_and_reserved == self.clock_seq_hi_and_reserved # && $uuid->node == self.node # && $uuid->time_hi_and_version == self.time_hi_and_version # && $uuid->time_low == self.time_low # && $uuid->time_mid == self.time_mid # ) # { # return true; # } # */ return ( other.__a == self.__a and other.__b == self.__b and other.__c == self.__c and other.__d == self.__d and other.__e == self.__e and other.__f == self.__f and other.__g == self.__g and other.__h == self.__h and other.__i == self.__i and other.__j == self.__j and other.__k == self.__k ) @staticmethod def __init_bits(): __pr_bits = False if Guid.__urand is not None: __pr_bits += Guid.__urand.read(16) if not self.__pr_bits: fp = open ( '/dev/urandom', 'rb' ) if fp is not False: __pr_bits += fp.read(16) fp.close() else: # If /dev/urandom isn't available (eg: in non-unix systems), use mt_rand(). __pr_bits = "" for cnt in range(0, 16): __pr_bits += chr ( __mt_rand ( 0, 255 ) ) return __pr_bits """ @brief Generates a Universally Unique IDentifier, version 4. This function generates a truly random UUID. The built in CakePHP String::uuid() function is not cryptographically secure. You should uses this function instead. @see http://tools.ietf.org/html/rfc4122#section-4.4 @see http://en.wikipedia.org/wiki/UUID @return UUID A UUID, made up of 32 hex digits and 4 hyphens. """ @staticmethod def generate(): uuid = Guid() __pr_bits = Guid.__init_bits() uuid.__a = (int(pr_bits[3]) << 24) | (int(pr_bits[2]) << 16) | (int(pr_bits[1]) << 8) | pr_bits[0] uuid.__b = ((int(pr_bits[5]) << 8) | pr_bits[4]) uuid.__c = ((int(pr_bits[7]) << 8) | pr_bits[6]) uuid.__d = pr_bits[8] uuid.__e = pr_bits[9] uuid.__f = pr_bits[10] uuid.__g = pr_bits[11] uuid.__h = pr_bits[12] uuid.__i = pr_bits[13] uuid.__j = pr_bits[14] uuid.__k = pr_bits[15] return uuid @staticmethod def __hexToChar(a : int) -> str: a = a & 0xf v = 0 if a > 9: v = a - 10 + 0x61 else: v = a + 0x30 return chr(v) @staticmethod def __hexsToChars(a : int, b : int, hex : bool = False): guidChars = "" if hex: guidChars = "0x" guidChars += Guid.__hexToChar(a >> 4) guidChars += Guid.__hexToChar(a) if hex: guidChars += ",0x" guidChars += Guid.__hexToChar(b >> 4) guidChars += Guid.__hexToChar(b) return guidChars # public function __toString() # { # } # public function __toStringFormat($includeDashes = true, $prefix = "{", $suffix = "}") # { # $guidChars = $prefix; # $guidChars += Guid.__hexsToChars(self._a >> 24, self._a >> 16) # $guidChars += Guid.__hexsToChars(self._a >> 8, self._a) # if ($includeDashes) $guidChars += '-'; # $guidChars += Guid.__hexsToChars(self._b >> 8, self._b) # if ($includeDashes) $guidChars += '-'; # $guidChars += Guid.__hexsToChars(self._c >> 8, self._c) # if ($includeDashes) $guidChars += '-'; # $guidChars += Guid.__hexsToChars(self._d, self._e) # if ($includeDashes) $guidChars += '-'; # $guidChars += Guid.__hexsToChars(self._f, self._g) # $guidChars += Guid.__hexsToChars(self._h, self._i) # $guidChars += Guid.__hexsToChars(self._j, self._k) # $guidChars += $suffix; # return $guidChars; # } def format(input : str): output = input output = output[0:8] + "-" + output[8:(8+4)] + "-" + output[12:12+4] + "-" + output[16:16+4] + "-" + output[20:] return "{" + output + "}" def get_value(self) -> str: return self.value def strip(self): guidChars = "" guidChars += Guid.__hexsToChars(self.__a >> 24, self.__a >> 16) guidChars += Guid.__hexsToChars(self.__a >> 8, self.__a) guidChars += Guid.__hexsToChars(self.__b >> 8, self.__b) guidChars += Guid.__hexsToChars(self.__c >> 8, self.__c) guidChars += Guid.__hexsToChars(self.__d, self.__e) guidChars += Guid.__hexsToChars(self.__f, self.__g) guidChars += Guid.__hexsToChars(self.__h, self.__i) guidChars += Guid.__hexsToChars(self.__j, self.__k) return guidChars.lower() def __str__(self): # //return self.format(strtoupper( sprintf ( '%08s%04s%04x%04x%012s', self.time_low, self.time_mid, self.time_hi_and_version, self.clock_seq_hi_and_reserved, self.node ) )) dash = True guidChars = "{" guidChars += Guid.__hexsToChars(self.__a >> 24, self.__a >> 16) guidChars += Guid.__hexsToChars(self.__a >> 8, self.__a) if (dash): guidChars += '-' guidChars += Guid.__hexsToChars(self.__b >> 8, self.__b) if (dash): guidChars += '-' guidChars += Guid.__hexsToChars(self.__c >> 8, self.__c) if (dash): guidChars += '-' guidChars += Guid.__hexsToChars(self.__d, self.__e) if (dash): guidChars += '-' guidChars += Guid.__hexsToChars(self.__f, self.__g) guidChars += Guid.__hexsToChars(self.__h, self.__i) guidChars += Guid.__hexsToChars(self.__j, self.__k) guidChars += "}" return guidChars.lower() @staticmethod def create(): from uuid import uuid4 u = uuid4() g = Guid.parse(str(u)) return g