Question

Lors de la création d'un UUID en Python, likeso:

>>> uuid.uuid1()
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')

Comment peut-on carte qui UUID dans une chaîne composée de l'alphabet majuscule AZ moins les caractères D, F, I, O, Q et U, ainsi que les chiffres numériques, ainsi que les caractères « + » et « = » . à savoir le à partir d'un nombre entier ou d'une chaîne sur l'ensemble de 32 caractères (OCR relativement sympathiques):

[ABCEGHJKLMNPRSTVWXYZ1234567890+=]

Je vais appeler cela l'ensemble de OCRf (OCR friendly).

Je voudrais avoir une fonction isomorphe:

def uuid_to_ocr_friendly_chars(uid)
    """takes uid, an integer, and transposes it into a string made 
       of the the OCRf set
    """
    ...

Ma première pensée est de passer par le processus de modification du UUID à la base 32. par exemple.

OCRf = "ABCEGHJKLMNPRSTVWXYZ1234567890+="

def uuid_to_ocr_friendly_chars(uid):
     ocfstr = ''
     while uid > 1:
        ocfstr += OCRf[uid % 32]
        uid /= 32
     return ocfstr

Cependant, je voudrais savoir si cette méthode est la meilleure et la plus rapide d'aller sur cette conversion - ou s'il y a une méthode plus simple et plus rapide (par exemple une commande interne, un algorithme plus intelligent, ou tout simplement une meilleure méthode).

Je suis reconnaissant pour votre entrée. Merci.

Était-ce utile?

La solution

Quelle importance accordez-vous à la « presser » la représentation de 18,75%, à savoir de 32 à 26 caractères? Parce que, si la sauvegarde de ce petit pourcentage d'octets n'est pas absolument crucial, quelque chose comme uid.hex.upper().replace('D','Z') fera ce que vous demandez (ne pas utiliser l'alphabet que vous mettez à la disposition, mais le seul coût de ce manque est que 18,75% « presser »).

Si presser vers le bas chaque octet dernier est crucial, je travaille sur 20 bits sous-chaînes de chacun - qui est 5 caractères hexadécimaux, 4 caractères dans votre alphabet funky. Il y a 6 de ceux (plus 8 bits qui restent, pour lesquels vous pouvez prendre le hex.upper().replace comme ci-dessus car il n'y a rien à gagner à faire quoi que ce soit amateur). Vous pouvez facilement obtenir les sous-chaînes en découpant .hex et tourner chacun en un int avec un int(theslice, 16). Ensuite, vous pouvez appliquer essentiellement le même algorithme que vous utilisez ci-dessus - mais l'arithmétique est fait sur un nombre beaucoup plus-petits, de sorte que le gain de vitesse devrait être matériel. En outre, ne construit pas la chaîne en boucle sur += - faire une liste de tous les « chiffres » et ''.join tous à la fin -. C'est aussi une amélioration de la performance

Autres conseils

>>> OCRf = 'ABCEGHJKLMNPRSTVWXYZ1234567890+='
>>> uuid = 'a8098c1a-f86e-11da-bd1a-00112444be1e'
>>> binstr = bin(int(uuid.replace("-",""),16))[2:].zfill(130)
>>> ocfstr = "".join(OCRf[int(binstr[i:i+5],2)] for i in range(0,130,5))
>>> ocfstr
'HLBJJB2+ETCKSP7JWACGYGMVW+'

Pour reconvertir à nouveau

>>> "%x"%(int("".join(bin(OCRf.index(i))[2:].zfill(5) for i in ocfstr),2))
'a8098c1af86e11dabd1a00112444be1e'
transtbl = string.maketrans(
  'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
  'ABCEGHJKLMNPRSTVWXYZ1234567890+='
)

uuidstr = uuid.uuid1()

print base64.b32encode(str(uuidstr).replace('-', '').decode('hex')).rstrip('=').translate(transtbl)

Oui, cette méthode Finalité me faire un peu mal, merci de demander.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top