Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gteissier
GitHub Repository: gteissier/erl-matter
Path: blob/master/complete-cookie.c
271 views
1
#include <stdio.h>
2
#include <stdint.h>
3
#include <stdlib.h>
4
#include <pthread.h>
5
#include <inttypes.h>
6
#include <string.h>
7
#include <assert.h>
8
9
#include "erldp.h"
10
11
static uint64_t next_random(uint64_t x);
12
static pthread_mutex_t output_lock;
13
14
int test_seed(uint64_t seed, const char *cookie, size_t size,
15
char *derived) {
16
uint64_t x;
17
int i;
18
19
x = seed;
20
21
for (i = size-1; i >= 0; i--) {
22
derived[i] = 'A' + ((26*x) / 0x1000000000);
23
if (cookie[i] != '.' && cookie[i] != derived[i]) {
24
return size - i;
25
}
26
x = next_random(x);
27
}
28
29
return 0;
30
}
31
32
static uint64_t next_random(uint64_t x) {
33
unsigned __int128 z = x;
34
z = (z * 17059465ULL + 1) & 0xfffffffff;
35
return (uint64_t) z;
36
}
37
38
struct interval {
39
uint64_t start;
40
uint64_t end;
41
char c;
42
};
43
44
static const struct interval intervals[26] = {
45
{0ULL, 2643056797ULL, 'A'},
46
{2643056798ULL, 5286113595ULL, 'B'},
47
{5286113596ULL, 7929170392ULL, 'C'},
48
{7929170393ULL, 10572227190ULL, 'D'},
49
{10572227191ULL, 13215283987ULL, 'E'},
50
{13215283988ULL, 15858340785ULL, 'F'},
51
{15858340786ULL, 18501397582ULL, 'G'},
52
{18501397583ULL, 21144454380ULL, 'H'},
53
{21144454381ULL, 23787511177ULL, 'I'},
54
{23787511178ULL, 26430567975ULL, 'J'},
55
{26430567976ULL, 29073624772ULL, 'K'},
56
{29073624773ULL, 31716681570ULL, 'L'},
57
{31716681571ULL, 34359738367ULL, 'M'},
58
{34359738368ULL, 37002795165ULL, 'N'},
59
{37002795166ULL, 39645851963ULL, 'O'},
60
{39645851964ULL, 42288908760ULL, 'P'},
61
{42288908761ULL, 44931965558ULL, 'Q'},
62
{44931965559ULL, 47575022355ULL, 'R'},
63
{47575022356ULL, 50218079153ULL, 'S'},
64
{50218079154ULL, 52861135950ULL, 'T'},
65
{52861135951ULL, 55504192748ULL, 'U'},
66
{55504192749ULL, 58147249545ULL, 'V'},
67
{58147249546ULL, 60790306343ULL, 'W'},
68
{60790306344ULL, 63433363140ULL, 'X'},
69
{63433363141ULL, 66076419938ULL, 'Y'},
70
{66076419939ULL, 68719476735ULL, 'Z'}
71
};
72
73
volatile int quit = 0;
74
75
struct worker {
76
pthread_t tid;
77
uint64_t start;
78
uint64_t end;
79
uint64_t incr;
80
const char *cookie;
81
};
82
83
static uint64_t revert_random(uint64_t x) {
84
unsigned __int128 z = x;
85
z = ((z-1)*67451848633ULL) & 0xfffffffff;
86
return (uint64_t) z;
87
}
88
89
static void *run(void *arg) {
90
struct worker *w = arg;
91
uint64_t seed, seed_1;
92
int ret;
93
char derived[20+1];
94
95
derived[20] = 0;
96
for (seed = w->start; seed <= w->end && !quit; seed += w->incr) {
97
if (test_seed(seed, w->cookie, 20, derived) == 0) {
98
ret = pthread_mutex_lock(&output_lock);
99
assert(ret == 0);
100
101
seed_1 = revert_random(seed);
102
103
printf("%s (seed = %" PRIu64 ")\n", derived, seed_1);
104
105
ret = pthread_mutex_unlock(&output_lock);
106
assert(ret == 0);
107
}
108
}
109
110
return NULL;
111
}
112
113
114
int main(int argc, char **argv) {
115
const char *cookie;
116
int n_workers = 8;
117
struct worker *workers;
118
int c;
119
int i;
120
int ret;
121
122
if (argc != 2) {
123
fprintf(stderr, "usage: %s <20 capital letters cookie>\n", argv[0]);
124
exit(1);
125
}
126
127
cookie = argv[1];
128
if (strlen(cookie) != 20) {
129
fprintf(stderr, "cookie must be 20 characters long\n");
130
exit(1);
131
}
132
133
for (i = 0 ; i < 20; i++) {
134
if ((cookie[i] < 'A' || cookie[i] > 'Z') && cookie[i] != '.') {
135
fprintf(stderr, "cookie must composed of uppercase letters only\n");
136
exit(1);
137
}
138
}
139
140
if (cookie[19] == '.') {
141
fprintf(stderr, "sorry cannot do first trial guessing for the time being\n");
142
exit(1);
143
}
144
145
146
c = cookie[19] - 'A';
147
148
ret = pthread_mutex_init(&output_lock, NULL);
149
assert(ret == 0);
150
151
workers = calloc(sizeof(*workers), n_workers);
152
assert(workers);
153
154
for (i = 0; i < n_workers; i++) {
155
workers[i].start = intervals[c].start + i;
156
workers[i].end = intervals[c].end;
157
workers[i].incr = n_workers;
158
workers[i].cookie = cookie;
159
160
ret = pthread_create(&workers[i].tid, NULL, run, &workers[i]);
161
assert(ret == 0);
162
}
163
164
for (i = 0; i < n_workers; i++) {
165
pthread_join(workers[i].tid, NULL);
166
}
167
168
return 0;
169
}
170
171
172