ffarquet
ffarquet

Reputation: 1283

Encode a list of ids in an elegant id

I am trying to find the best way to encode a list of 10 integers (approximately between 1 and 10000) into a single id (I need a one-to-one function between a list of integers to a single integer or string).

I tried base64 (which is good because it is reversible), but the result is much longer than the input and that's quite bad.

For example, if I want to encode 12-54-235-1223-21-765-43-763-9522-908,

base64 gives me MTItNTQtMjM1LTEyMjMtMjEtNzY1LTQzLTc2My05NTIyLTkwOA==

Hashing functions are bad because I can't recover the input easily.

Maybe I could use the fact that I have only numbers as input and use number theory facts, someone has an idea?

Upvotes: 0

Views: 226

Answers (1)

Kevin
Kevin

Reputation: 76244

If the integers are guaranteed to be smaller than 10^9, you could encode them as:

[number of digits in 1st number][1st number][number of digits in 2nd number][2nd number][...]

So 12,54,235,1223,21,765,43,763,9522,908 yields 21225432354122322137652433763495223908.

Sample Python implementation:

def numDigits(x):
    if x < 10:
        return 1
    return 1 + numDigits(x/10)

def encode(nums):
    ret = ""
    for number in nums:
        ret = ret + str(numDigits(number)) + str(number)
    return ret

def decode(id):
    nums = []
    while id != "":
        numDigits = int(id[0])
        id = id[1:] #remove first char from id
        number = int(id[:numDigits])
        nums.append(number)
        id = id[numDigits:] #remove first number from id
    return nums

nums = [12,54,235,1223,21,765,43,763,9522,908]
id = encode(nums)
decodedNums = decode(id)
print id
print decodedNums

Result:

21225432354122322137652433763495223908
[12, 54, 235, 1223, 21, 765, 43, 763, 9522, 908]

Upvotes: 1

Related Questions