Last active
February 24, 2023 22:32
-
-
Save emlyn/18d2dbed8b17dfb92c87 to your computer and use it in GitHub Desktop.
Base64 Fixed Point Calculator in Python
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
#!/usr/bin/env python3 | |
import sys | |
def get6bits(bytes, offset): | |
"Get 6-bit value from offset in bits in a string" | |
byte_offset = offset // 8 | |
bit_offset = offset % 8 | |
if bit_offset <= 2: | |
# The 6 bits of input are all in the same byte: | |
val = ord(bytes[byte_offset]) >> (2 - bit_offset) | |
else: | |
# Take the last bits of the first input byte and combine with some bits of the next byte: | |
val = ((ord(bytes[byte_offset]) << (bit_offset - 2)) | | |
(ord(bytes[byte_offset + 1]) >> (10 - bit_offset))) | |
# Mask out 6 bits | |
return val % 64 | |
def b64fp(): | |
"Yield the base64 fixed point (infinite) string one character at a time." | |
# Base 64 alphabet: | |
alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \ | |
"abcdefghijklmnopqrstuvwxyz" + \ | |
"0123456789+/" | |
# Choose an arbitrary 3-char seed | |
input = '...' | |
prev = None | |
# Repeatedly base64 encode it (taking 3 chars) until it doesn't change. | |
# Note: for the normal base64 alphabet there is exactly one fixed point. | |
# If you change the alphabet there may be no fixed point (loops indefinitely) | |
# or multiple fixed points (changes depending on the seed value). | |
while input != prev: | |
prev = input | |
input = ''.join(alphabet[get6bits(input, i*6)] for i in range(3)) | |
# Yield first 3 chars (18 bits of input): | |
yield from input | |
# After 18 bits, we are 2 bits into the 3rd (last) input char: | |
input = input[-1] | |
bit = 2 | |
while True: | |
val = get6bits(input, bit) | |
# We have used up 6 bits of the input | |
bit += 6 | |
if bit >= 8: | |
# We've finished with the first byte of input, so throw it away and reset bit counter: | |
input = input[1:] | |
bit -= 8 | |
# Look up the character for the next 6 bits and append it to the input | |
input += alphabet[val] | |
# And yield that next character | |
yield input[-1] | |
def main(num=None): | |
if num: num = int(num) | |
for n, c in enumerate(b64fp()): | |
print(c, end='', flush=True) | |
if num and n >= num - 1: | |
print() | |
break | |
if __name__ == '__main__': | |
main(*sys.argv[1:]) |
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
Vm0wd2QyUXlVWGxWV0d4V1YwZDRWMVl3WkRSV01WbDNXa1JTVjAxV2JETlhhMUpU | |
VmpBeFYySkVUbGhoTVVwVVZtcEJlRll5U2tWVWJHaG9UVlZ3VlZadGNFSmxSbGw1 | |
VTJ0V1ZXSkhhRzlVVmxaM1ZsWmFkR05GU214U2JHdzFWVEowVjFaWFNraGhSemxW | |
Vm14YU0xWnNXbUZrUjA1R1UyMTRVMkpIZHpGV1ZFb3dWakZhV0ZOcmFHaFNlbXhX | |
Vm0xNFlVMHhXbk5YYlVaclVqQTFSMVV5TVRSVk1rcElaSHBHVjFaRmIzZFdha1po | |
VjBaT2NtRkhhRk5sYlhoWFZtMHhORmxWTUhoWGJrNVlZbFZhY2xWcVFURlNNVlY1 | |
VFZSU1ZrMXJjRWxhU0hCSFZqRmFSbUl6WkZkaGExcG9WakJhVDJOdFJraGhSazVz | |
WWxob1dGWnRNSGhPUm14V1RVaG9XR0pyTlZsWmJGWmhZMnhXY1ZGVVJsTk5WbFkx | |
VkZaU1UxWnJNWEpqUld4aFUwaENTRlpxUm1GU2JVbDZXa1prYUdFeGNHOVdha0po | |
VkRKT2RGSnJhR2hTYXpWeldXeG9iMWRHV25STlNHaFBVbTE0VjFSVmFHOVhSMHB5 | |
VGxac1dtSkdXbWhaTW5oWFkxWkdWVkpzVGs1V2JGa3hWa1phVTFVeFduSk5XRXBx | |
VWxkNGFGVXdhRU5UUmxweFVtMUdVMkpWYkRaWGExcHJZVWRGZUdOSE9WZGhhMHBv | |
VmtSS1QyUkdTbkpoUjJoVFlYcFdlbGRYZUc5aU1XUkhWMjVTVGxOSGFGQlZiVEUw | |
VmpGU1ZtRkhPVmhTTUhCNVZHeGFjMWR0U2tkWGJXaGFUVzVvV0ZreFdrZFdWa3B6 | |
VkdzMVYySkdhM2hXYTFwaFZURlZlRmR1U2s1WFJYQnhWV3hrTkdGR1ZYZGhSVTVV | |
VW14d2VGVnRNVWRWTWtwV1lrUmFXR0V4Y0hKWlZXUkdaVWRPU0U5V1pHaGhNSEJ2 | |
Vm10U1MxUXlVa2RUYmtwb1VqSm9WRmxZY0ZkbGJHUllaVWM1YVUxWFVraFdNalZU | |
Vkd4T1NHRkdRbFppVkVVd1ZtcEdVMVp0UmtoUFZtaFRUVWhDTlZaSGVHRmpNV1Iw | |
VTJ0a1dHSlhhR0ZVVnpWdlYwWnJlRmRyWkZkV2EzQjZWa2R6TVZZeVNrZGhNMmhY | |
WVRGd2FGWlVSbFpsUm1SMVUyczFXRkpZUW5oV1YzaHJUa2RHUjFaWVpHaFNWVFZW | |
VlcxNGQyVkdWblJOVldSV1RXdHdWMWxyVW1GWFIwVjRZMGhLV2xaWFVrZGFWV1JQ | |
VTBVNVYxcEhhR2hOU0VKMlZtMTBVMU14VVhsVmEyUlVZbXR3YjFWcVNtOVdSbXha | |
WTBaa2JHSkhVbGxhVldNMVlWVXhXRlZyYUZkTmFsWlVWa2Q0VDFOSFJrZFJiRnBw | |
VmtWVmQxWnRjRWRWTVZwMFVtdG9VRlp0YUZSVVZXaERUbFphU0dWSFJtcE5WMUl3 | |
VlRKMGExZEhTbGhoUjBaVlZucFdkbFl3V25KbFJtUnlXa1prVjJFelFqWldhMlI2 | |
VFZaWmVWTnJaR2hOTW1oWVdWUkdkMkZHV2xWU2JGcHNVbTFTTVZVeWN6RlhSa3Ba | |
VVc1b1YxWXphSEpVYTJSSFVqRmFXVnBIYUZOV1ZGWldWbGN4TkdReVZrZFdibEpP | |
VmxkU1YxUlhkSGRXTVd4eVZXMUdXRkl3VmpSWk1HaExWMnhhV0ZWclpHRldWMUpR | |
VlRCVk5WWXhjRWhoUjJoT1UwVktNbFp0TVRCVk1VMTRWVmhzVm1FeVVsVlpiWFIz | |
WWpGV2NWTnRPVmRTYlhoYVdUQmFhMkpIU2toVmJHeGhWbGROTVZsV1ZYaFhSbFp5 | |
WVVaa1RtRnNXbFZXYTJRMFZERk9TRkpyWkZKaVJuQndWbXRXVm1ReFduUmpSV1JX | |
VFZad01GVnRkRzlWUmxwMFlVWlNWVlpYYUVSVWJGcGhVMGRXU0ZKdGNFNVdNVWwz | |
VmxSS01HRXhaRWhUYkdob1VqQmFWbFp1Y0Zka2JGbDNWMjVLYkZKdFVubFhhMXBy | |
VmpKRmVsRnFXbGRoTWxJMlZGWmFXbVZXVG5KYVIyaE9UVzFvV1ZkV1VrZGtNa1pI | |
VjJ4V1UySkdjSE5WYlRGVFRWWlZlV042UmxoU2EzQmFWVmMxYjFZeFdYcGhTRXBW | |
WVRKU1NGVnFSbUZYVm5CSVlVWk9WMVpHV2xkV2JHTjRUa2RSZVZaclpGZGliRXBQ | |
Vm14a1UxWXhVbGhrU0dSWFRWZDRlVlpYTVVkWFJrbDNWbXBTV2sxSGFFeFdNbmho | |
VjBaV2NscEhSbGRXTVVwUlZsUkNWazVXV1hoalJXaG9VakpvVDFVd1ZrdE5iRnAw | |
VFZSQ1ZrMVZNVFJXVm1oelZtMUZlVlZzVmxwaVdGSXpXV3BHVjJOV1RuUlBWbVJU | |
WWxob1lWZFVRbUZoTWtwSVUydG9WbUpIZUdoV2JHUk9UVlpzVjFaWWFGaFNiRnA1 | |
V1ZWYWExUnRSbk5YYkZaWFlUSlJNRlpFUms5VFJrcHlXa1pLYVZKdVFuZFdiWFJY | |
Vm0xUmVGZHVVbXBTVjFKWFZGWmFkMDFHVm5Sa1J6bFdVbXh3TUZsVldsTldWbHBZ | |
WVVWU1ZXSkdjR2hWTUdSWFUwWktkR05GTlZkTlZXd3pWbXhTUzAxSFJYaGFSV2hV | |
WWtkb2IxVnFRbUZXYkZwMVkwWmthMkpHYkROV01qVkxZa1pLZEZWdWJGaGhNWEJ5 | |
Vm1wS1JtVnNSbkZYYkdSb1RXeEpNbFpHV21GWGJWWlhWRzVLWVZJeWFFOVVWekZ2 | |
VjFaa1YxVnJaR3ROYTFwSVZqSjRWMVV5U2tkalNFNVdZbFJHVkZSV1dsWmxWMDQy | |
VW14b1UyRXpRbUZXVm1NeFlqRlplRmRZY0doVFJYQldXVlJLVTFOR1ZuRlNiVVpZ | |
Vm01Q1NWbFZXazlXTVZwSFYyeGtWMkpIVGpSVWEyUlNaVlphY2xwR1pHbGlSWEJR | |
Vm0xNGExVXhXWGhWYkdoclUwZFNXRlJXWkRSbFZscFlUVlZrV0ZKcmJETldiWEJU | |
VjJzeFNHRkZlRmROYm1ob1ZqQmFWMk5zY0VoU2JHUlhUVlZ3VWxac1VrTldhelZY | |
VjFob2FsSlhhRzlWYWtwdlZERlZkMVpyZEU1aVJuQXdWRlpTUTFack1WWk5WRkpY | |
Vm0xb2VsWnRNVVpsVmxaelZteHdhVmRHU1hwWFYzQkhWakpPVjFSdVVsQldiVkpV | |
V1d4b2IxbFdaRlZSYlVab1RXdHdTVlV5ZEc5V2JVcElaVWRvVjJKSFVrOVVWbHB6 | |
VmpGYVdXRkdhRk5pUm5BMVYxWldZV0V4VW5SU2JrNVlZa1phV0ZsVVNsSk5SbHBG | |
VW1zNVZGSnJjSGxYYTFwTFlWWktkVkZ1WkZkaVdGSllWbTB4VW1WR1pIVlZiWEJU | |
VmpGS1dGWkdXbUZrTURGSFZtNVNhMUo2YkZkVmJYaDNUVVpzVmxkc1RsZFdiSEJa | |
V1ZWV1UxWlhTa2RqUjJoV1RVZFNXRlV3V2t0a1IwNUdUbFprVGxaWGQzcFdiWGhU | |
VXpBeFNGSllhR0ZTVjJoVldXdGtiMkl4Vm5GUmJVWlhZa1p3TVZrd1dtdGhNa3BI | |
WWtST1YwMXFWa3haYTFwTFpFWldkV0pHYUdoTldFSjVWbTF3UzFKdFZuTlNia1pZ | |
WWtkU2IxUlhlRXBOYkZwSFYyMUdXR0pXV2xoV1J6VkxXVlpKZVdGRk9WVldla1oy | |
VmpGYWExWXhWbkphUjNST1lURndTVlpxU2pSV01WVjVVMnRrYWxORk5WZFpiRkpI | |
VmtaU1YxZHNXbXhXTURReVZXMTRiMVV5UlhwUmJVWlhWbTFOZUZscVJscGxSbVJa | |
WTBkb1ZGSllRbGRYVmxKTFZURk9SMVp1UmxOaVZWcFpWbTAxUTFOV2JGWlhhemxY | |
VFZad1NGWXllR3RXTWtwSVZHcFNWV0V5VWxOYVZscGhZMnh3UjFwSGJHbFNXRUpS |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment