12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /* tslint:disable:no-bitwise false */
- 'use strict';
- import bigInt = require('big-integer');
- import crypto = require('crypto');
- import zlib = require('zlib');
- /**
- * Decodes the data.
- */
- export default function(id: number, iv: Buffer|string, data: Buffer|string,
- done: (err?: Error, result?: Buffer) => void)
- {
- try
- {
- decompress(decrypt(id, iv, data), done);
- } catch (e)
- {
- done(e);
- }
- }
- /**
- * Decrypts the data.
- */
- function decrypt(id: number, iv: Buffer|string, data: Buffer|string)
- {
- const ivBuffer = typeof iv === 'string' ? new Buffer(iv, 'base64') : iv;
- const dataBuffer = typeof data === 'string' ? new Buffer(data, 'base64') : data;
- const decipher = crypto.createDecipheriv('aes-256-cbc', key(id), ivBuffer);
- decipher.setAutoPadding(false);
- return Buffer.concat([decipher.update(dataBuffer), decipher.final()]);
- }
- /**
- * Decompresses the data.
- */
- function decompress(data: Buffer, done: (err: Error, result?: Buffer) => void)
- {
- try
- {
- zlib.inflate(data, done);
- } catch (e)
- {
- done(null, data);
- }
- }
- /**
- * Generates a key.
- */
- function key(subtitleId: number): Buffer
- {
- const hash = secret(20, 97, 1, 2) + magic(subtitleId);
- const result = new Buffer(32);
- result.fill(0);
- crypto.createHash('sha1').update(hash).digest().copy(result);
- return result;
- }
- /**
- * Generates a magic number.
- */
- function magic(subtitleId: number): number
- {
- const base = Math.floor(Math.sqrt(6.9) * Math.pow(2, 25));
- const hash = bigInt(base).xor(subtitleId).toJSNumber();
- const multipliedHash = bigInt(hash).multiply(32).toJSNumber();
- return bigInt(hash).xor(hash >> 3).xor(multipliedHash).toJSNumber();
- }
- /**
- * Generates a secret string based on a Fibonacci sequence.
- */
- function secret(size: number, modulo: number, firstSeed: number, secondSeed: number): string
- {
- let currentValue = firstSeed + secondSeed;
- let previousValue = secondSeed;
- let result = '';
- for (let i = 0; i < size; i += 1)
- {
- const oldValue = currentValue;
- result += String.fromCharCode(currentValue % modulo + 33);
- currentValue += previousValue;
- previousValue = oldValue;
- }
- return result;
- }
|