You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.9 KiB

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