21 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #youtube_dl/extractor/iqiyi.py: interpreter for "iQiyi SDK"
  2. #ln=\z
  3. class IqiyiSDK(object):
  4. def __init__(self, target, ip, timestamp):
  5. self.target = target
  6. self.ip = ip
  7. self.timestamp = timestamp
  8. @staticmethod
  9. def split_sum(data):
  10. return compat_str(sum(map(lambda p: int(p, 16), list(data))))
  11. @staticmethod
  12. def digit_sum(num):
  13. if isinstance(num, int):
  14. num = compat_str(num)
  15. return compat_str(sum(map(int, num)))
  16. def even_odd(self):
  17. even = self.digit_sum(compat_str(self.timestamp)[::2])
  18. odd = self.digit_sum(compat_str(self.timestamp)[1::2])
  19. return even, odd
  20. def preprocess(self, chunksize):
  21. self.target = md5_text(self.target)
  22. chunks = []
  23. for i in range(32 // chunksize):
  24. chunks.append(self.target[chunksize * i:chunksize * (i + 1)])
  25. if 32 % chunksize:
  26. chunks.append(self.target[32 - 32 % chunksize:])
  27. return chunks, list(map(int, self.ip.split('.')))
  28. def mod(self, modulus):
  29. chunks, ip = self.preprocess(32)
  30. self.target = chunks[0] + ''.join(map(lambda p: compat_str(p % modulus), ip))
  31. def split(self, chunksize):
  32. modulus_map = {
  33. 4: 256,
  34. 5: 10,
  35. 8: 100,
  36. }
  37. chunks, ip = self.preprocess(chunksize)
  38. ret = ''
  39. for i in range(len(chunks)):
  40. ip_part = compat_str(ip[i] % modulus_map[chunksize]) if i < 4 else ''
  41. if chunksize == 8:
  42. ret += ip_part + chunks[i]
  43. else:
  44. ret += chunks[i] + ip_part
  45. self.target = ret
  46. def handle_input16(self):
  47. self.target = md5_text(self.target)
  48. self.target = self.split_sum(self.target[:16]) + self.target + self.split_sum(self.target[16:])
  49. def handle_input8(self):
  50. self.target = md5_text(self.target)
  51. ret = ''
  52. for i in range(4):
  53. part = self.target[8 * i:8 * (i + 1)]
  54. ret += self.split_sum(part) + part
  55. self.target = ret
  56. def handleSum(self):
  57. self.target = md5_text(self.target)
  58. self.target = self.split_sum(self.target) + self.target
  59. def date(self, scheme):
  60. self.target = md5_text(self.target)
  61. d = time.localtime(self.timestamp)
  62. strings = {
  63. 'y': compat_str(d.tm_year),
  64. 'm': '%02d' % d.tm_mon,
  65. 'd': '%02d' % d.tm_mday,
  66. }
  67. self.target += ''.join(map(lambda c: strings[c], list(scheme)))
  68. def split_time_even_odd(self):
  69. even, odd = self.even_odd()
  70. self.target = odd + md5_text(self.target) + even
  71. def split_time_odd_even(self):
  72. even, odd = self.even_odd()
  73. self.target = even + md5_text(self.target) + odd
  74. def split_ip_time_sum(self):
  75. chunks, ip = self.preprocess(32)
  76. self.target = compat_str(sum(ip)) + chunks[0] + self.digit_sum(self.timestamp)
  77. def split_time_ip_sum(self):
  78. chunks, ip = self.preprocess(32)
  79. self.target = self.digit_sum(self.timestamp) + chunks[0] + compat_str(sum(ip))
  80. class IqiyiSDKInterpreter(object):
  81. def __init__(self, sdk_code):
  82. self.sdk_code = sdk_code
  83. def run(self, target, ip, timestamp):
  84. self.sdk_code = decode_packed_codes(self.sdk_code)
  85. functions = re.findall(r'input=([a-zA-Z0-9]+)\(input', self.sdk_code)
  86. sdk = IqiyiSDK(target, ip, timestamp)
  87. other_functions = {
  88. 'handleSum': sdk.handleSum,
  89. 'handleInput8': sdk.handle_input8,
  90. 'handleInput16': sdk.handle_input16,
  91. 'splitTimeEvenOdd': sdk.split_time_even_odd,
  92. 'splitTimeOddEven': sdk.split_time_odd_even,
  93. 'splitIpTimeSum': sdk.split_ip_time_sum,
  94. 'splitTimeIpSum': sdk.split_time_ip_sum,
  95. }
  96. for function in functions:
  97. if re.match(r'mod\d+', function):
  98. sdk.mod(int(function[3:]))
  99. elif re.match(r'date[ymd]{3}', function):
  100. sdk.date(function[4:])
  101. elif re.match(r'split\d+', function):
  102. sdk.split(int(function[5:]))
  103. elif function in other_functions:
  104. other_functions[function]()
  105. else:
  106. raise ExtractorError('Unknown funcion %s' % function)
  107. return sdk.target