forked from iotaledger/kerl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
conv.py
151 lines (118 loc) · 3.86 KB
/
conv.py
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/python3
# -*- coding: utf-8 -*-
BYTE_HASH_LENGTH = 48
TRIT_HASH_LENGTH = 243
tryte_table = {
'9': [ 0, 0, 0], # 0
'A': [ 1, 0, 0], # 1
'B': [-1, 1, 0], # 2
'C': [ 0, 1, 0], # 3
'D': [ 1, 1, 0], # 4
'E': [-1, -1, 1], # 5
'F': [ 0, -1, 1], # 6
'G': [ 1, -1, 1], # 7
'H': [-1, 0, 1], # 8
'I': [ 0, 0, 1], # 9
'J': [ 1, 0, 1], # 10
'K': [-1, 1, 1], # 11
'L': [ 0, 1, 1], # 12
'M': [ 1, 1, 1], # 13
'N': [-1, -1, -1], # -13
'O': [ 0, -1, -1], # -12
'P': [ 1, -1, -1], # -11
'Q': [-1, 0, -1], # -10
'R': [ 0, 0, -1], # -9
'S': [ 1, 0, -1], # -8
'T': [-1, 1, -1], # -7
'U': [ 0, 1, -1], # -6
'V': [ 1, 1, -1], # -5
'W': [-1, -1, 0], # -4
'X': [ 0, -1, 0], # -3
'Y': [ 1, -1, 0], # -2
'Z': [-1, 0, 0], # -1
}
# Invert for trit -> tryte lookup
trit_table = {tuple(v): k for k, v in tryte_table.items()}
def trytes_to_trits(trytes):
trits = []
for tryte in trytes:
trits.extend(tryte_table[tryte])
return trits
def trits_to_trytes(trits):
trytes = []
trits_chunks = [trits[i:i + 3] for i in range(0, len(trits), 3)]
for trit in trits_chunks:
trytes.extend(trit_table[tuple(trit)])
return ''.join(trytes)
def convertToTrits(bytes_k):
bigInt = convertBytesToBigInt(bytes_k)
trits = convertBigintToBase(bigInt, 3, TRIT_HASH_LENGTH)
return trits
def convertToBytes(trits):
bigInt = convertBaseToBigint(trits, 3)
bytes_k = convertBigintToBytes(bigInt)
return bytes_k
def convertBytesToBigInt(ba):
# copy of array
bytesArray = list(map(lambda x: x, ba))
# number sign in MSB
signum = (1 if bytesArray[0] >= 0 else -1)
if signum == -1:
# sub1
for pos in reversed(range(len(bytesArray))):
sub = (bytesArray[pos] & 0xFF) - 1
bytesArray[pos] = (sub if sub <= 0x7F else sub - 0x100)
if bytesArray[pos] != -1:
break
# 1-compliment
bytesArray = list(map(lambda x: ~x, bytesArray))
# sum magnitudes and set sign
return sum((x & 0xFF) << pos * 8 for (pos, x) in
enumerate(reversed(bytesArray))) * signum
def convertBigintToBytes(big):
bytesArrayTemp = [(abs(big) >> pos * 8) % (1 << 8) for pos in
range(48)]
# big endian and balanced
bytesArray = list(map(lambda x: (x if x <= 0x7F else x - 0x100),
reversed(bytesArrayTemp)))
if big < 0:
# 1-compliment
bytesArray = list(map(lambda x: ~x, bytesArray))
# add1
for pos in reversed(range(len(bytesArray))):
add = (bytesArray[pos] & 0xFF) + 1
bytesArray[pos] = (add if add <= 0x7F else add - 0x100)
if bytesArray[pos] != 0:
break
return bytesArray
def convertBaseToBigint(array, base):
bigint = 0
for i in range(len(array)):
bigint += array[i] * (base ** i)
return bigint
def convertBigintToBase(bigInt, base, length):
result = []
is_negative = bigInt < 0
quotient = abs(bigInt)
MAX = (base-1) // 2
if is_negative:
MAX = base // 2
for i in range(length):
quotient, remainder = divmod(quotient, base)
if remainder > MAX:
# Lend 1 to the next place so we can make this digit negative.
quotient += 1
remainder -= base
if is_negative:
remainder = remainder * -1
result.append(remainder)
return result
def convert_sign(byte):
"""
Convert between signed and unsigned bytes
"""
if byte < 0:
return 256 + byte
elif byte > 127:
return -256 + byte
return byte