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
|
# xref unique ID hash calculation
#
# Copyright (C) 2020 David Lamparter for NetDEF, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; see the file COPYING; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import struct
from hashlib import sha256
def bititer(data, bits, startbit=True):
"""
just iterate the individual bits out from a bytes object
if startbit is True, an '1' bit is inserted at the very beginning
goes <bits> at a time, starts at LSB.
"""
bitavail, v = 0, 0
if startbit and len(data) > 0:
v = data.pop(0)
yield (v & ((1 << bits) - 1)) | (1 << (bits - 1))
bitavail = 9 - bits
v >>= bits - 1
while len(data) > 0:
while bitavail < bits:
v |= data.pop(0) << bitavail
bitavail += 8
yield v & ((1 << bits) - 1)
bitavail -= bits
v >>= bits
def base32c(data):
"""
Crockford base32 with extra dashes
"""
chs = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
o = ""
if type(data) == str:
data = [ord(v) for v in data]
else:
data = list(data)
for i, bits in enumerate(bititer(data, 5)):
if i == 5:
o = o + "-"
elif i == 10:
break
o = o + chs[bits]
return o
def uidhash(filename, hashstr, hashu32a, hashu32b):
"""
xref Unique ID hash used in FRRouting
"""
filename = "/".join(filename.rsplit("/")[-2:])
hdata = filename.encode("UTF-8") + hashstr.encode("UTF-8")
hdata += struct.pack(">II", hashu32a, hashu32b)
i = sha256(hdata).digest()
return base32c(i)
|