20
2017
09

qq视频真实地址获取 ckey算法PHP版本。

<?php
class tea {
	private $seed = 0xdead;
	private $maxf = 0xffffffff;
	private $token = [0xfa, 0x82, 0xde, 0xb5, 0x2d, 0x4b, 0xba, 0x31, 0x39, 0x6,  0x33, 0xee, 0xfb, 0xbf, 0xf3, 0xb6];

	public function __construct() {
	}
	private function str_sum($s) {
		$n = 0;
		foreach($s as $i) {
			$n = $this->maxf & intval($n * 131 + $i);
		}
		return 0x7fffffff & $n;
	}

	private function pack_str($t, $d) {
		$l = strlen($d);
		$t[] = ($l & 0xff00) >> 8;
		$t[] = $l & 0xff;
		for($i=0;$i < $l;$i++) {
			$t[] = ord($d[$i]);
		}
		return $t;
	}

	private function rands(){
		if ($this->seed == 0) {
			$this->seed = 123459876;
		}
		$k1 = $this->maxf & (-2836 * (floor($this->seed / 127773)));
		$k2 = $this->maxf & (16807 * (floor($this->seed % 127773)));
		$this->seed = $this->maxf & ($k1 + $k2);
		if ($this->seed < 0) {
			$this->seed += PHP_INT_MAX;
		}
		return $this->seed;
	}

	private function new_pack($v, $d) {
		foreach($d as $s) {
			$k = str_split(pack("I", $s));
			krsort($k);
			foreach($k as $c) {
				$v[] = ord($c);
			}
		}
		return $v;
	}

	private function new_unpack($d) {
		$str = '';
		$ret = [];
		foreach($d as $b) $str .= chr($b);
		$t = range(0, strlen($str), 4);
		for($i=0;$i < count($t) - 1;$i++) {
			$s = substr($str, $t[$i], 4);
			$n = unpack('N', $s)[1];
			if ($n < 0){
				$n += 4294967296;
			}
			$ret[] = $n;
		}
		return $ret;
	}

	private function tea_encrypt($v, $k) {
		$s = (integer) 0;
		$k = $this->new_unpack($k);
		$v = $this->new_unpack($v);
		$bjz_int = PHP_INT_MAX;
		for($i=0;$i < 16;$i++){
			$s += 0x9e3779b9;
			$s &= $this->maxf;
			$v[0] += ($s + $v[1]) ^ (($v[1] >> 5) + $k[1]) ^ (($v[1] << 4) + $k[0]);
			$v[0] &= $this->maxf;
			$v[1] += ($s + $v[0]) ^ (($v[0] >> 5) + $k[3]) ^ (($v[0] << 4) + $k[2]);
			$v[1] &= $this->maxf;
		}
		return $this->new_pack([], $v);
	}

	private function oi_symmetry_encrypt2($raw, $key) {
		$data = [];
		$temp = [0, 0, 0, 0, 0, 0, 0, 0];
		$pad_salt_body_zero_len = count($raw) + 10;
		$pad_len = $pad_salt_body_zero_len % 8;
		if ($pad_len) $pad_len = 8 - $pad_len;
		array_push($data, $this->rands() & 0xf8 | $pad_len);
		while($pad_len + 2) {
			array_push($data, $this->rands() & 0xff);
			$pad_len = $pad_len - 1;
		}
		foreach($raw as $rd) $data[] = $rd;
		array_push($data, 0, 0 ,0, 0, 0, 0, 0);
		$dt = array_slice($data, 0, 8);
		$enc = $this->tea_encrypt($dt, $key);
		$length = count($data);
		$d = range(8, $length, 8);
		foreach($d as $i) {
			if ($i != $length) {
				$dk = array_slice($data, $i);
				for($j=0;$j < 8;$j++) {
					$dk[$j] = $dk[$j] ^ $enc[$i - 8 + $j];
				}
				$dk = $this->tea_encrypt($dk, $key);
				for($j=0;$j < 8;$j++) {
					$dk[$j] = ($dk[$j] ^ $data[$i - 8 + $j] ^ $temp[$j]);
					array_push($enc, $dk[$j]);
					$temp[$j] = $enc[$i - 8 + $j];
				}
			}
		}
		return $enc;
	}

	public function getCkey($vid, $ver = '3.2.19.356', $platform = 1400603, $stdfrom = 'bcng') {
		$out = '';$data = [];$tm = $_SERVER['REQUEST_TIME'];
		$guid = '21F9945F5114779E123F0E34C7B8E54500BA5E369';
		$data = $this->new_pack($data, [21507, 3168485562]);
		$data = $this->new_pack($data, [$platform]);
		$data = $this->new_pack($data, [9999, $tm]);
		$data = $this->pack_str($data, $stdfrom);
		$data = $this->pack_str($data, rand());
		$data = $this->pack_str($data, $ver);
		$data = $this->pack_str($data, $vid);
		$data = $this->pack_str($data, $guid);
		array_push($data, 0, 1, 52, 0, 1, 52, 0, 0, 0, 1, 0, 0, 0, 0);
		$len = count($data);
		array_unshift($data, $len & 0xff);
		array_unshift($data, ($len & 0xff00) >> 8);
		$enc = $this->oi_symmetry_encrypt2($data, $this->token);
		$pad = [0, 0, 0, 0, 0xff & $this->rands(), 0xff & $this->rands(), 0xff & $this->rands(), 0xff & $this->rands()];
		$pad[0] = $pad[4] ^ 71 & 0xff;
		$pad[1] = $pad[5] ^ -121 & 0xff;
		$pad[2] = $pad[6] ^ -84 & 0xff;
		$pad[3] = $pad[7] ^ -86 & 0xff;
		foreach($enc as $b) $pad[] = $b;
		$pad = $this->new_pack($pad, [$this->str_sum($data)]);
		foreach($pad as $b) $out .= chr($b);
		$out = base64_encode($out);
		$out = str_replace('=', '', $out);
		$out = str_replace('+', '_', $out);
		$out = str_replace('/', '-', $out);
		return urlencode($out);
	}
}

$t = new tea();
$ckey = $t->getCkey(empty($_GET['vid']) ? "x0015remj2b" : trim($_GET['vid']));
echo "{\"ckey\":\"$ckey\"}";


« 上一篇 下一篇 »