0

Sites like youtube have their ID's using the full character range to make an ID eg dQw4w9WgXcQ. I am wondering how this would be done by selecting a number and turning it into a compressed number using the full range of basic characters like this.

a>b>c>d>e> ect >azy>azz>aAa>aAb

I have written this in javascript and it was hideous for how I did it was embedded for loops going through an array of possible characters. I really hope I don't need to do that again but the best I can find in an efficient manner is int to hex but hex does not cover the full range of characters I need.

Hello World
  • 168
  • 6
  • http://stackoverflow.com/questions/2257441/random-string-generation-with-upper-case-letters-and-digits-in-python – Bryan Newman May 06 '17 at 19:06
  • That gives a random sequence - the OP wants an integer->string mapping. – PaulMcG May 06 '17 at 19:07
  • If you want a securely random integer → string mapping, that’s not really easy: https://crypto.stackexchange.com/questions/712/converting-a-stream-cipher-into-a-block-cipher If you’re okay with 1 → a, though, just encode the number in base 62 by dividing it by 62 repeatedly and taking the remainder. – Ry- May 06 '17 at 19:09

1 Answers1

1

This might be close to what you have in mind:

def int_to_string_fns(chars):
    num_chars = len(chars)
    char_to_i = dict((c,i) for i, c in enumerate(chars))

    # create 2 functions for the given characters, 
    # one to convert an int to a string, and one to 
    # convert a string back to the corresponding int
    def _to_string(i, minsize=0):

        pad = []
        ret = []
        if minsize:
            maxval = num_chars ** (minsize-1)
            while maxval > max(i, 1):
                pad.append(chars[0])
                maxval /= num_chars

        if i > 0:
            while i:
                i, c = divmod(i, num_chars)
                ret.append(chars[c])
        else:
            ret.append(chars[0])

        return ''.join(pad + ret[::-1])

    def _from_string(s):
        mult = num_chars
        ret = 0
        for c in s:
            ret *= mult
            ret += char_to_i[c]
        return ret

    return _to_string, _from_string

enc,dec = int_to_string_fns("ABCDEFGHIJKLMNOP")
print(enc(100))
print(dec("GE"))

for i in range(100,110):
    print(i, enc(i), dec(enc(i)))

prints

GE
100

100 GE 100
101 GF 101
102 GG 102
103 GH 103
104 GI 104
105 GJ 105
106 GK 106
107 GL 107
108 GM 108
109 GN 109
PaulMcG
  • 62,419
  • 16
  • 94
  • 130