Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

import math 

import string 

import sys 

 

ALPHABET = string.digits + string.ascii_letters 

PY2 = sys.version_info[0] == 2 

 

8 ↛ 12line 8 didn't jump to line 12, because the condition on line 8 was never falseif PY2: 

def ord_byte(char): 

return ord(char) 

else: 

def ord_byte(byte): 

return byte 

 

 

def ceildiv(dividend, divisor): 

''' integer ceiling division ''' 

return (dividend + divisor - 1) // divisor 

 

 

def calc_chunklen(alph_len): 

''' 

computes the ideal conversion ratio for the given alphabet. 

A ratio is considered ideal when the number of bits in one output 

encoding chunk that don't add up to one input encoding chunk is minimal. 

''' 

binlen, enclen = min([ 

(i, i*8 / math.log(alph_len, 2)) 

for i in range(1, 7) 

], key=lambda k: k[1] % 1) 

 

return binlen, int(enclen) 

 

 

def encode(digest): 

chunklen = calc_chunklen(len(ALPHABET)) 

nchunks = ceildiv(len(digest), chunklen[0]) 

binstr = digest.ljust(nchunks * chunklen[0], b'\0') 

 

return ''.join([ 

_encode_chunk(binstr, i) for i in range(0, nchunks) 

]) 

 

def _encode_chunk(data, index): 

''' 

gets a chunk from the input data, converts it to a number and 

encodes that number 

''' 

chunk = _get_chunk(data, index) 

return _encode_long(_chunk_to_long(chunk)) 

 

 

def _encode_long(val): 

''' 

encodes an integer of 8*chunklen[0] bits using the specified 

alphabet 

''' 

chunklen = calc_chunklen(len(ALPHABET)) 

return ''.join([ 

ALPHABET[(val//len(ALPHABET)**i) % len(ALPHABET)] 

for i in reversed(range(chunklen[1])) 

]) 

 

 

def _chunk_to_long(chunk): 

''' 

parses a chunk of bytes to integer using big-endian representation 

''' 

chunklen = calc_chunklen(len(ALPHABET)) 

return sum([ 

256**(chunklen[0]-1-i) * ord_byte(chunk[i]) 

for i in range(chunklen[0]) 

]) 

 

 

def _get_chunk(data, index): 

''' 

partition the data into chunks and retrieve the chunk at the given index 

''' 

chunklen = calc_chunklen(len(ALPHABET)) 

return data[index*chunklen[0]:(index+1)*chunklen[0]]