Created
August 1, 2021 09:48
-
-
Save Ghostscypher/0e73650afd1ed8b20a4fe6ad15872d52 to your computer and use it in GitHub Desktop.
Perform a canot pairing of n-length
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
''' | |
Translated from: | |
en.wikipedia.org/wiki/Pairing_function, both the pairing | |
and upairing functions | |
''' | |
def cantor_pairing(x, y): | |
return int((((x + y +1) * (x + y)) / 2) + y) | |
def cantor_unpair(z): | |
w = math.floor((math.sqrt(8 * z + 1) - 1) / 2) | |
t = (w * w + w) / 2 | |
# The second part of unpairing | |
y = z - t | |
x = w - y | |
return (int(x), int(y)) | |
''' | |
Used to perform some tests | |
''' | |
def some_test(): | |
for i in range(10): | |
for j in range(10): | |
print("*" * 20) | |
paired = cantor_pairing(i, j) | |
print("pair(%d, %d): %d" %(i, j, paired)) | |
unpaired = cantor_unpair(paired) | |
print("unpair(%d): %s" %(paired, unpaired)) | |
converted = chr(paired) | |
print("Encoded character of %d is %c " %(paired, converted)) | |
print("Decoded character %c is %d" %(converted, ord(converted))) | |
print("*" * 20) | |
print("\n") | |
''' | |
a and b are the input digits | |
output should be pair_length characters long, default is 4 | |
''' | |
def pair(a, b, pair_length = 4): | |
# Check that a and b are integers, do not accept | |
# alphabetic characters | |
if((not isinstance(a, int)) or (not isinstance(b, int))): | |
# Should throw an error instead | |
return null | |
# We've verified the values supplied are integers only | |
a = str(a) | |
b = str(b) | |
if(len(a) > pair_length or len(b) > pair_length): | |
# should throw an error or something | |
return null | |
# The string is in the allowed range, pad any missing values, e.g. if | |
# input is 12 pad it to make it 0012 i.e. always 4 characters long | |
a = str("0" * (pair_length - len(a))) + a | |
b = str("0" * (pair_length - len(b))) + b | |
# Where the result of this pairing function will be stored | |
result = "" | |
# For each character in | |
for i in range(pair_length): | |
result += chr(cantor_pairing(int(a[i]), int(b[i]))) | |
# Return the final result which should be pair_length characters long | |
return result | |
# Reverses the above function | |
def unpair(s): | |
# Explicitlymake sure that s is a string | |
s = str(s) | |
# the x value | |
x = -1 | |
# the y value | |
y = -1 | |
# For each character in s | |
for char in s: | |
temp = cantor_unpair(ord(char)) | |
if x == -1 or y == -1: | |
x = temp[0] | |
y = temp[1] | |
else: | |
x = (x * 10) + temp[0] | |
y = (y * 10) + temp[1] | |
return (int(x), int(y)) | |
if __name__ == "__main__": | |
# Uncomment the line below to run some test | |
#some_test() | |
# Begining of the main thing | |
#pairing | |
result = pair(9999, 9999) | |
print("Paired result is '%s' which is %d characters long " %(result, len(result))) | |
# Unpairing | |
unpaired_result = unpair(result) | |
print("unpaired result ") | |
print(unpaired_result) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment