]>
Commit | Line | Data |
---|---|---|
f5756f38 PH |
1 | #!/usr/bin/env python |
2 | ||
3 | # Generate youtube signature algorithm from test cases | |
4 | ||
5 | import sys | |
6 | ||
7 | tests = [ | |
257a2501 | 8 | # 88 |
f5756f38 PH |
9 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[]}|:;?/>.<", |
10 | "J:|}][{=+-_)(*&;%$#@>MNBVCXZASDFGH^KLPOIUYTREWQ0987654321mnbvcxzasdfghrklpoiuytej"), | |
257a2501 | 11 | # 87 |
f5756f38 PH |
12 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<", |
13 | "!?;:|}][{=+-_)(*&^$#@/MNBVCXZASqFGHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"), | |
257a2501 | 14 | # 86 - vfl_ymO4Z 2013/06/27 |
f5756f38 | 15 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<", |
23300d71 | 16 | "ertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!/#$%^&*()_-+={[|};?@"), |
257a2501 | 17 | # 85 |
f5756f38 PH |
18 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", |
19 | "{>/?;}[.=+-_)(*&^%$#@!MqBVCXZASDFwHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytr"), | |
257a2501 | 20 | # 84 |
f5756f38 PH |
21 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<", |
22 | "<.>?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWe098765432rmnbvcxzasdfghjklpoiuyt1"), | |
257a2501 | 23 | # 83 |
f5756f38 PH |
24 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<", |
25 | "D.>/?;}[{=+_)(*&^%$#!MNBVCXeAS<FGHJKLPOIUYTREWZ0987654321mnbvcxzasdfghjklpoiuytrQ"), | |
257a2501 | 26 | # 82 |
f5756f38 PH |
27 | ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKHGFDSAZXCVBNM!@#$%^&*(-+={[};?/>.<", |
28 | "Q>/?;}[{=+-(*<^%$#@!MNBVCXZASDFGHKLPOIUY8REWT0q&7654321mnbvcxzasdfghjklpoiuytrew9"), | |
29 | ] | |
30 | ||
31 | def find_matching(wrong, right): | |
32 | idxs = [wrong.index(c) for c in right] | |
33 | return compress(idxs) | |
34 | return ('s[%d]' % i for i in idxs) | |
35 | ||
36 | def compress(idxs): | |
37 | def _genslice(start, end, step): | |
38 | starts = '' if start == 0 else str(start) | |
39 | ends = ':%d' % (end+step) | |
40 | steps = '' if step == 1 else (':%d' % step) | |
41 | return 's[%s%s%s]' % (starts, ends, steps) | |
42 | ||
43 | step = None | |
44 | for i, prev in zip(idxs[1:], idxs[:-1]): | |
45 | if step is not None: | |
46 | if i - prev == step: | |
47 | continue | |
48 | yield _genslice(start, prev, step) | |
49 | step = None | |
50 | continue | |
51 | if i - prev in [-1, 1]: | |
52 | step = i - prev | |
53 | start = prev | |
54 | continue | |
55 | else: | |
56 | yield 's[%d]' % prev | |
57 | if step is None: | |
58 | yield 's[%d]' % i | |
59 | else: | |
60 | yield _genslice(start, i, step) | |
61 | ||
62 | def _assert_compress(inp, exp): | |
63 | res = list(compress(inp)) | |
64 | if res != exp: | |
65 | print('Got %r, expected %r' % (res, exp)) | |
66 | assert res == exp | |
67 | _assert_compress([0,2,4,6], ['s[0]', 's[2]', 's[4]', 's[6]']) | |
68 | _assert_compress([0,1,2,4,6,7], ['s[:3]', 's[4]', 's[6:8]']) | |
69 | _assert_compress([8,0,1,2,4,7,6,9], ['s[8]', 's[:3]', 's[4]', 's[7:5:-1]', 's[9]']) | |
70 | ||
71 | def gen(wrong, right, indent): | |
72 | code = ' + '.join(find_matching(wrong, right)) | |
73 | return 'if len(s) == %d:\n%s return %s\n' % (len(wrong), indent, code) | |
74 | ||
75 | def genall(tests): | |
76 | indent = ' ' * 8 | |
77 | return indent + (indent + 'el').join(gen(wrong, right, indent) for wrong,right in tests) | |
78 | ||
79 | def main(): | |
80 | print(genall(tests)) | |
81 | ||
82 | if __name__ == '__main__': | |
83 | main() |