-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrand.py
More file actions
executable file
·101 lines (75 loc) · 2.51 KB
/
Copy pathrand.py
File metadata and controls
executable file
·101 lines (75 loc) · 2.51 KB
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
#!/usr/bin/env python3
import argparse
import datetime
import random
import string
a = 1664525
b = 1013904223
M = 2**32
MASK32 = 2**32 - 1
def lcg(x):
"""Linear congruent generator"""
return (a * x + b) % M
def generate_block(x):
words = []
# Each block is 1024-bit
for _ in range(1024//32):
x = lcg(x)
words.append(x)
return words, x
def random_key():
key = ''
for _ in range(256):
key += random.choice(string.ascii_letters + string.digits)
return key
def generate_seed(key, timestamp):
"""
XOR each 32-bit component together.
key is 256-bit ascii, timestamp 128-bit ascii
NOTE: I am not certain that the CommsProc intends the key to be
ASCII. I am also unsure of the byte order I should convert the
ASCII with.
"""
ret = 0
key = key.encode('ascii')
key = int.from_bytes(key, byteorder='big')
ret ^= key & MASK32
ret ^= (key >> 32) & MASK32
ret ^= (key >> 64) & MASK32
ret ^= (key >> 96) & MASK32
ret ^= (key >> 128) & MASK32
ret ^= (key >> 160) & MASK32
ret ^= (key >> 224) & MASK32
timestamp = timestamp.encode('ascii')
timestamp = int.from_bytes(timestamp, byteorder='big')
ret ^= timestamp & MASK32
ret ^= (timestamp >> 32) & MASK32
ret ^= (timestamp >> 64) & MASK32
ret ^= (timestamp >> 96) & MASK32
return ret
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Generate CubeQuest random data')
parser.add_argument('--team-key', type=str, help='Team key',
default=random_key())
parser.add_argument('--timestamp', type=str, default=None,
help='''Timestamp to use instead of current time.
Must be in YYYYMMDDHHMMSS.S format''')
parser.add_argument('-i', '--iterations', type=int, default=3,
help='Number of blocks to output')
args = parser.parse_args()
print('Team key: %s' % args.team_key)
if args.timestamp:
timestamp = args.timestamp
else:
timestamp = datetime.datetime.now(datetime.timezone.utc)
timestamp = timestamp.strftime('%Y%m%d%H%M%S.%f')
# Silly hack to reduce precision to 1/10 sec
timestamp = timestamp[:-5]
print('Timestamp: %s' % timestamp)
seed = generate_seed(args.team_key, timestamp)
print('Seed: %d' % seed)
x = seed
print('Blocks:')
for i in range(args.iterations):
block, x = generate_block(x)
print('%d: %s' % (i, block))