Advertisement
Guest User

Rate my code, /g/

a guest
Jun 3rd, 2016
147
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.89 KB | None | 0 0
  1. import hashlib
  2. import itertools
  3. from collections import Counter
  4.  
  5.  
  6. """
  7. The bishop wakes up in the center of a room. He is drunk and stumbles around,
  8. putting down coins at each position he passes. The bishop only walks diagonally
  9. much like bishops normally found on chess boards. The fingerprint determines
  10. his steps.
  11.  
  12. The room is 17 positions wide and 9 positions long. The bishop starts in the
  13. center of the room.
  14. """
  15.  
  16.  
  17. # the bishop starts in the center of the room
  18. STARTING_POSITION = (8, 4)
  19. ROOM_DIMENSIONS = (17, 9)
  20.  
  21. # encode start and end positions
  22. COIN_VALUE_STARTING_POSITION = 15
  23. COIN_VALUE_ENDING_POSITION = 16
  24.  
  25. BORDER = '+' + '-' * ROOM_DIMENSIONS[0] + '+\n'
  26.  
  27.  
  28. def hex_byte_to_binary(hex_byte):
  29.     """
  30.    Convert a hex byte into a string representation of its bits,
  31.    e.g. 'd4' => '11010100'
  32.    """
  33.     assert len(hex_byte) == 2
  34.     dec = int(hex_byte, 16)
  35.     return bin(dec)[2:].zfill(8)
  36.  
  37.  
  38. def bit_pairs(binary):
  39.     """
  40.    Convert a word into bit pairs little-endian style.
  41.    '10100011' => ['11', '00', '10', '10']
  42.    """
  43.     def take(n, iterable):
  44.         "Return first n items of the iterable as a list"
  45.         return list(itertools.islice(iterable, n))
  46.     def all_pairs(iterable):
  47.         while True:
  48.             pair = take(2, iterable)
  49.             if not pair:
  50.                 break
  51.             yield ''.join(pair)
  52.     pairs = list(all_pairs(iter(binary)))
  53.     return list(reversed(pairs))
  54.  
  55.  
  56. class Direction(object):
  57.     """Encode a sense of direction."""
  58.     def __init__(self, dx, dy):
  59.         self.dx = dx
  60.         self.dy = dy
  61.  
  62. NW = Direction(dx=-1, dy=-1)
  63. NE = Direction(dx=1, dy=-1)
  64. SW = Direction(dx=-1, dy=1)
  65. SE = Direction(dx=1, dy=1)
  66.  
  67.  
  68. def directions_from_fingerprint(fingerprint):
  69.     """
  70.    Convert the fingerprint (16 hex-encoded bytes separated by colons)
  71.    to steps (one of four directions: NW, NE, SW, SE).
  72.    """
  73.     direction_lookup = {
  74.         '00': NW,
  75.         '01': NE,
  76.         '10': SW,
  77.         '11': SE,
  78.     }
  79.     for hex_byte in fingerprint.split(':'):
  80.         binary = hex_byte_to_binary(hex_byte)
  81.         # read each bit-pair in each word right-to-left (little endian)
  82.         for bit_pair in bit_pairs(binary):
  83.             direction = direction_lookup[bit_pair]
  84.             yield direction
  85.  
  86.  
  87. def move(position, direction):
  88.     """
  89.    Returns new position given current position and direction to move in.
  90.    """
  91.     x, y = position
  92.     MAX_X = ROOM_DIMENSIONS[0] - 1
  93.     MAX_Y = ROOM_DIMENSIONS[1] - 1
  94.     assert 0 <= x <= MAX_X
  95.     assert 0 <= y <= MAX_Y
  96.     new_x, new_y = x + direction.dx, y + direction.dy
  97.     # the drunk bishop is hindered by the wall.
  98.     new_x = 0 if new_x <= 0 else min(new_x, MAX_X)
  99.     new_y = 0 if new_y <= 0 else min(new_y, MAX_Y)
  100.     return new_x, new_y
  101.  
  102.  
  103. def stumble_around(fingerprint):
  104.     room = Counter()
  105.     position = STARTING_POSITION
  106.     for direction in directions_from_fingerprint(fingerprint):
  107.         position = move(position, direction)
  108.         room[position] += 1  # drop coin
  109.     # mark start and end positions
  110.     room[STARTING_POSITION] = COIN_VALUE_STARTING_POSITION
  111.     room[position] = COIN_VALUE_ENDING_POSITION
  112.     return room
  113.  
  114.  
  115. def coin(value):
  116.     """
  117.    Display the ascii representation of a coin.
  118.    """
  119.     return {
  120.         0: ' ',
  121.         1: '.',
  122.         2: 'o',
  123.         3: '+',
  124.         4: '=',
  125.         5: '*',
  126.         6: 'B',
  127.         7: 'O',
  128.         8: 'X',
  129.         9: '@',
  130.         10: '%',
  131.         11: '&',
  132.         12: '#',
  133.         13: '/',
  134.         14: '^',
  135.         COIN_VALUE_STARTING_POSITION: 'S',
  136.         COIN_VALUE_ENDING_POSITION: 'E',
  137.     }.get(value, '!')
  138.  
  139.  
  140. def display_room(room):
  141.     X, Y = ROOM_DIMENSIONS
  142.     def room_as_strings():
  143.         yield BORDER
  144.         for y in range(Y):
  145.             yield '|'
  146.             for x in range(X):
  147.                 yield coin(room[(x,y)])
  148.             yield '|\n'
  149.         yield BORDER
  150.     return ''.join(room_as_strings())
  151.  
  152.  
  153. ################################################################################
  154.  
  155.  
  156. def drunken_bishop_colon(fingerprint):
  157.     """
  158.     Inserts colon to hex strings.
  159.     """
  160.     assert len(fingerprint) % 2 == 0
  161.     result = ""
  162.     for i in range(len(fingerprint)//2):
  163.         result =  result + fingerprint[2*i:2*i+2] + ':'
  164.     return result[:-1]
  165.  
  166.  
  167. def drunken_bishop_check(fingerprint):
  168.     if ":" not in fingerprint:
  169.         return False # Hex pairs without colon
  170.     else:
  171.         return True # Hex pairs with colon
  172.  
  173.  
  174. def drunken_bishop(fingerprint):
  175.     """
  176.     Creates a piece of art base on 32 hex
  177.     """
  178.     if drunken_bishop_check(fingerprint) == False:
  179.         fingerprint = drunken_bishop_colon(fingerprint)
  180.     room = stumble_around(fingerprint)
  181.     return display_room(room)
  182.  
  183.  
  184. def drunken_bishop_tops(fingerprint):
  185.     """
  186.     Like drunken_bishop but without the bottom frame
  187.     """
  188.     if drunken_bishop_check(fingerprint) == False:
  189.         fingerprint = drunken_bishop_colon(fingerprint)
  190.     room = stumble_around(fingerprint)
  191.     return display_room(room)[:-(ROOM_DIMENSIONS[0]+3)]
  192.  
  193.  
  194. def drunken_bishop_multiple(fingerprint):
  195.     """
  196.     Vertically stacked drunken_bishop
  197.     """
  198.     if drunken_bishop_check(fingerprint) == False:
  199.         fingerprint = drunken_bishop_colon(fingerprint)
  200.     finger = [fingerprint[i:i+48].rstrip(':') for i in range(0, len(fingerprint), 48)]
  201.     picture = [drunken_bishop_tops(i) for i in finger]
  202.     return ''.join(picture) + BORDER
  203.  
  204.  
  205. ################################################################################
  206.  
  207.  
  208. def drunken_bishop_scrape(fingerprint):
  209.     room = drunken_bishop_multiple(fingerprint)
  210.     scan = room.split('\n')[:-1]
  211.     return [item[:-1] for item in scan]
  212.  
  213.  
  214. def drunken_bishop_merge(list):
  215.     super_list = []
  216.     for item in list:
  217.         super_list.append(drunken_bishop_scrape(item))
  218.     output = [''] * len(super_list[0])
  219.     for y in range(len(super_list[0])):
  220.         for x in range(len(super_list)):
  221.             output[y] += super_list[x][y]
  222.         output[y] += output[y][0]
  223.     return '\n'.join(output) + '\n'
  224.  
  225.  
  226. def drunken_bishop_1x1(password):
  227.     """
  228.     A 1x1 drunken_bishop rectangle based on MD-5
  229.     """
  230.     password = password.encode('utf-8')
  231.     md5 = hashlib.md5(password).hexdigest()
  232.     md5_finger = [md5[i:i+32] for i in range(0, len(md5), 32)]
  233.     return drunken_bishop_merge(md5_finger)
  234.  
  235.  
  236. def drunken_bishop_1x2(password):
  237.     """
  238.     A 1x2 drunken_bishop rectangle based on SHA-256
  239.     """
  240.     password = password.encode('utf-8')
  241.     sha_256 = hashlib.sha256(password).hexdigest()
  242.     sha_finger = [sha_256[i:i+32] for i in range(0, len(sha_256), 32)]
  243.     return drunken_bishop_merge(sha_finger)
  244.  
  245.  
  246. def drunken_bishop_2x2(password):
  247.     """
  248.     A 2x2 drunken_bishop rectangle based on SHA-512
  249.     """
  250.     password = password.encode('utf-8')
  251.     sha_512 = hashlib.sha512(password).hexdigest()
  252.     sha_finger = [sha_512[i:i+64] for i in range(0, len(sha_512), 64)]
  253.     return drunken_bishop_merge(sha_finger)
  254.  
  255.  
  256. def drunken_bishop_2x3(password):
  257.     """
  258.     A 2x3 drunken_bishop rectangle based on SHA-256/512
  259.     """
  260.     password = password.encode('utf-8')
  261.     sha_256 = hashlib.sha256(password).hexdigest()
  262.     sha_512 = hashlib.sha512(password).hexdigest()
  263.     sha_ultra = sha_256 + sha_512
  264.     sha_finger = [sha_ultra[i:i+64] for i in range(0, len(sha_ultra), 64)]
  265.     return drunken_bishop_merge(sha_finger)
  266.  
  267.  
  268. def drunken_bishop_3x3(password):
  269.     """
  270.     A 3x3 drunken_bishop rectangle based on SHA-256/384/512
  271.     """
  272.     password = password.encode('utf-8')
  273.     sha_256 = hashlib.sha256(password).hexdigest()
  274.     sha_384 = hashlib.sha384(password).hexdigest()
  275.     sha_512 = hashlib.sha512(password).hexdigest()
  276.     sha_extreme = sha_256 + sha_384 + sha_512
  277.     sha_finger = [sha_extreme[i:i+96] for i in range(0, len(sha_extreme), 96)]
  278.     return drunken_bishop_merge(sha_finger)
  279.  
  280. def drunken_bishop_unused(password):
  281.     password = password.encode('utf-8')
  282.     sha_160 = hashlib.sha1(password).hexdigest()
  283.     sha_224 = hashlib.sha224(password).hexdigest()
  284.     sha_unused = sha_160 + sha_224
  285.     sha_finger = [sha_unused[i:i+32] for i in range(0, len(sha_unused), 32)]
  286.     return drunken_bishop_merge(sha_finger)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement