Skip to content

Instantly share code, notes, and snippets.

@forsakendaemon
Last active July 27, 2016 10:42
Show Gist options
  • Save forsakendaemon/674f004a21013270211fffc867d6d244 to your computer and use it in GitHub Desktop.
Save forsakendaemon/674f004a21013270211fffc867d6d244 to your computer and use it in GitHub Desktop.
# N.B. The following values work. Technically, you can use any s and p with p a primitive root modulo s.
# It works best if you use an s that is one more than a multiple of three. (e.g. 4, 7, 10, 13)
# It will work for any x up to 2^{s - 1} - 1
# inv calculates is the inverse of p in \mathbb{Z}_{s}.
# s p
# 1 0
# 2 1
# 3 2
# 4 3
# 5 2,3
# 6 5
# 7 3,5
# 9 2,5
# 10 3,7
# 11 2,6,7,8
# 13 2,6,7,11
# 14 3,5
# 17 3,5,6,7,10,11,12,14
# 18 5,11
# 19 2,3,10,13,14,15
# 22 7,13,17,19
# 23 5,7,10,11,14,15,17,19,20,21
# 25 2,3,8,12,13,17,22,23
# 26 7,11,15,19
# 27 2,5,11,14,20,23
# 29 2,3,8,10,11,14,15,18,19,21,26,27
# 31 3,11,12,13,17,21,22,24
# 34 3,5,7,11,23,27,29,31
# 37 2,5,13,15,17,18,19,20,22,24,32,35
# 38 3,13,15,21,29,33
# 41 6,7,11,12,13,15,17,19,22,24,26,28,29,30,34,35
# 43 3,5,12,18,19,20,26,28,29,30,33,34
# 46 5,7,11,15,17,19,21,33,37,43
# 47 5,10,11,13,15,19,20,22,23,26,29,30,31,33,35,38,39,40,41,43,44,45
# 49 3,5,10,12,17,24,26,33,38,40,45,47
# 50 3,13,17,23,27,33,37,47
# 53 2,3,5,8,12,14,18,19,20,21,22,26,27,31,32,33,34,35,39,41,45,48,50,51
# 54 5,11,23,29,41,47
# 58 3,11,15,19,21,27,31,37,39,43,47,55
# 59 2,6,8,10,11,13,14,18,23,24,30,31,32,33,34,37,38,39,40,42,43,44,47,50,52,54,55,56
# 61 2,6,7,10,17,18,26,30,31,35,43,44,51,54,55,59
# 62 3,11,13,17,21,43,53,55
# 67 2,7,11,12,13,18,20,28,31,32,34,41,44,46,48,50,51,57,61,63
# 71 7,11,13,21,22,28,31,33,35,42,44,47,52,53,55,56,59,61,62,63,65,67,68,69
s = 13
p = 7
x = 473245
# First, take your number and turn it into a bitstring of the appropriate length.
y = bin(int(x))[2:].zfill(s - 1)
print(y)
def encode(y, s, p):
l = ["*"] * (s - 1)
i = 1
tmp = y[0]
for t in range(s):
l[i - 1] = tmp
tmp = y[i - 1]
i = i * p % s
return ''.join(l)
def inv(s, p):
for x in range(s):
if x * p % s == 1:
return x
return None
def decode(y, s, p):
return encode(y, s, inv(s, p))
def arr2int(arr):
return int(''.join(arr), 2)
# Now, we can encode that bitstring of an appropriate length using encode
print(encode(y, s, p))
# And turn that result into a triplet of numbers (that you can then turn into words the way you had before) up to 2^{(s - 1)/3 - 1}
print(list(map(arr2int, zip(*[iter(encode(y, s, p))]*((s - 1)//3)))))
# Decoding is pretty easy too
print(decode(encode(y, s, p), s, p))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment