URI: 
       atelier.dcgi - bitreich-bitmasquerade - Scripts for bitreich's new years eve bitmasqurade
   DIR Log
   DIR Files
   DIR Refs
       ---
       atelier.dcgi (5477B)
       ---
            1 #!/usr/bin/env python
            2 # coding=utf-8
            3 
            4 from functools import reduce
            5 import re
            6 import sys
            7 import hashlib
            8 import base64
            9 
           10 geomyidae_host = "server"
           11 geomyidae_port = "port"
           12 bitmask_selection = [ '010101010101', '110001100011', '001110011100',
           13                       '101010101010', '100000100001', '011111111110',
           14                       '000010010000', '100010001001', '010010001000',
           15                       '100110001110', '111111101111', '011000100010']
           16 bitwise_selection = ['Flip', 'Set', 'Clear', 'Shift-Right', 'Shift-Left',
           17              'Turnaround']
           18 bitwise_operations = {'Flip' : lambda a, b: a ^ b,
           19                       'Set' : lambda a, b: a | b,
           20                       'Clear' : lambda a, b: a & b,
           21                       'Turnaround' : lambda a, b: ~a & ~b,
           22                       'Shift-Right' : lambda a, b: a >> 3 | b >> 3,
           23                       'Shift-Left' : lambda a, b: a << 3 | b << 3}
           24 
           25 def string_to_binary(s, bits):
           26     return ''.join([format(ord(c), '0{}b'.format(bits)) for c in s])
           27 
           28 def strip_char_to_ascii_range(s, start, end):
           29     range = [format(ord(a), 'x') for a in [start, end]]
           30     patt = r'[^\x{}-\x{}]+'.format(*range)
           31     return re.sub(patt, '', s)
           32 
           33 def strip_to_max_len(s):
           34     return s[:16]
           35 
           36 def print_nick_fail():
           37     print("Pardon, but I'll need your name")
           38 
           39 def print_step_1_template(nick, hashnick):
           40     gph_menu_link = lambda s: \
           41         '[1|{}|atelier.dcgi?{} {} {}|{}|{}]'.format(s, nick, hashnick, s,
           42                                                       geomyidae_host, geomyidae_port)
           43     gph_links = '\n'.join(map(gph_menu_link, bitmask_selection))
           44     with open('step_1.txt', 'r') as file:
           45         print(file.read().format(nick, gph_links))
           46 
           47 def print_step_2_template(nick, hashnick, bitmask):
           48     gph_menu_link = lambda s: \
           49         '[1|{}|atelier.dcgi?{} {} {} {}|{}|{}]'.format(s, nick, hashnick, bitmask, s,
           50                                                       geomyidae_host, geomyidae_port)
           51     gph_links = '\n'.join(map(gph_menu_link, bitwise_selection))
           52     with open('step_2.txt', 'r') as file:
           53         print(file.read().format(nick, gph_links))
           54 
           55 def print_completion(nick, bitmask, bitwise, mask):
           56     with open('step_complete.txt', 'r') as file:
           57         print(file.read().format(nick, bitmask, bitwise, mask))
           58 
           59 def make_mask(nick, bitmask, bitwise):
           60     bits = len(nick)
           61     binary_nick = string_to_binary(nick, bits)
           62     # print(binary_nick)
           63     def bit_picker(remaining, accm=""):
           64         if len(accm) == 0:
           65             # Recursion entry point: accumulate first element of
           66             # the list.
           67             return bit_picker(remaining[1:], remaining[0:1])
           68         if remaining == "":
           69             # Recursion exit point: return the accumulated elements.
           70             return accm
           71         # Main loop: return the current element that corresponds
           72         # with the current multiple of the remaining chars
           73         multiple = int(len(remaining)/bits)
           74         if (len(remaining) % bits) == multiple:
           75             accm = accm + remaining[0:1]
           76             # print(remaining)
           77             return bit_picker(remaining[1:], accm)
           78         return bit_picker(remaining[1:], accm)
           79     selected_bits = bit_picker(binary_nick)
           80     bitmask = bitmask[:len(selected_bits)]
           81     bin_1 = int(selected_bits, 2)
           82     bin_2 = int(bitmask, 2)
           83     return bin(bitwise_operations[bitwise](bin_2, bin_1))\
           84         [2:].zfill(len(selected_bits))
           85 
           86 def print_args_fail():
           87     print("Pardon, but something's not working.")
           88 
           89 def print_bitmask_fail():
           90     print("Pardon, but that bitmask isn't available.")
           91 
           92 def main(args):
           93     geomyidae_search = args[1]
           94     geomyidae_args = args[2].split(' ') # tab splitting
           95     if geomyidae_search:
           96         # Get the search result, which will be this
           97         # person's nick, and ask them to pick a bitmask from
           98         # the list printed out in the step 1 template.
           99         nick = strip_char_to_ascii_range(geomyidae_search, '!', '~')
          100         m = hashlib.sha256()
          101         m.update(nick.encode())
          102         m.update("bitmasquerade".encode())
          103         hashnick = base64.b64encode(m.digest()).decode()
          104         nick = strip_to_max_len(nick)
          105         hashnick = strip_to_max_len(hashnick)
          106         if nick != '':
          107             print_step_1_template(nick, hashnick)
          108         else:
          109             print_nick_fail()
          110         sys.exit()
          111     # Validate and clear up the input from the bitmask
          112     # selection.
          113     if len(geomyidae_args) < 3:
          114         print_args_fail()
          115         sys.exit()
          116     nick = strip_char_to_ascii_range(geomyidae_args[0], '!', '~')
          117     nick = strip_to_max_len(nick)
          118     hashnick = strip_char_to_ascii_range(geomyidae_args[1], '!', '~')
          119     hashnick = strip_to_max_len(hashnick)
          120     bitmask = geomyidae_args[2]
          121     if nick == '':
          122         print_nick_fail()
          123         sys.exit()
          124     if bitmask not in bitmask_selection:
          125         print_bitmask_fail()
          126         sys.exit()
          127     if len(geomyidae_args) == 3:
          128         # Get the prson to choose their bitwise operation.
          129         print_step_2_template(nick, hashnick, bitmask)
          130     else:        #
          131         bitwise = geomyidae_args[3]
          132         if bitwise not in bitwise_selection:
          133             print_bitmask_fail()
          134             sys.exit()
          135         # Finish up by making combining the nick, bitmask,
          136         # and bitwise operation.
          137         mask = str(make_mask(nick, bitmask, bitwise))
          138         if mask.startswith("b"):
          139             mask = mask.replace("b", "")
          140         print_completion(nick, bitmask[:len(nick)], bitwise, mask)
          141     sys.exit()
          142 
          143 if __name__ == "__main__":
          144     sys.exit(main(sys.argv))