# public benthaman /lwn-digits

### Subversion checkout URL

You can clone with HTTPS or Subversion.

 ``` a46e025d » benthaman ``` 2011-05-26 decode and encode messages into numbers 1 #!/usr/bin/python 2 3 import sys 4 import random 5 import itertools 6 from math import sqrt 7 8 class Pfactor(object): 9 def __init__(self): 10 # bah, not implemented 11 self.cache = [] 12 13 def __call__(self, x): 14 factorlist = [] 15 16 if x == 1: 17 factorlist.append(x) 18 while x % 2 == 0: 19 factorlist.append(2) 20 x /= 2 21 limit = 1 + int(sqrt(x)) 22 for factor in range(3, limit, 2): 23 while x % factor == 0: 24 factorlist.append(factor) 25 x /= factor 26 if x > 1: 27 factorlist.append(x) 28 29 return factorlist 30 pfactor = Pfactor() 31 32 if len(sys.argv) != 1 + 1: 33 msg = "What a load of nonsense" 34 else: 35 msg = sys.argv[1] 36 charset_letters = sorted(list(set(msg))) 37 # optional, output different results 38 random.shuffle(charset_letters) 39 modulo = len(charset_letters) 40 while len(pfactor(modulo)) != 1: 41 modulo += 1 42 43 limit = 9999 44 for charset in itertools.permutations(charset_letters): 45 factor = [] 46 n = 0 47 for letter in msg: 48 index = charset.index(letter) 49 candidate = n * modulo + index + 1 50 # find the smallest n such that: 51 # factor[i] = n * modulo + index + 1 is prime and 52 # factor[i] > factor[i - 1] 53 while candidate < limit and not ( 54 len(pfactor(candidate)) == 1 and (len(factor) == 0 or 55 candidate > factor[-1])): 56 n += 1 57 candidate = n * modulo + index + 1 58 59 if candidate >= limit: 60 continue 61 else: 62 print "factor= %d, %d * %d + %d + 1" % (candidate, n, modulo, index,) 63 factor.append(candidate) 64 65 if candidate >= limit: 66 print "next try" 67 continue 68 else: 69 print modulo 70 print "".join(charset) 71 print reduce(lambda o1, o2: o1 * o2, factor) 72 sys.exit()