-1) { # 索引范围校验 $bytesof5bits[] = $b; } else { // CLogUtil::console("b ($b)is not a valid index "); } } $by8bits = self::fetch5BitByte($bytesof5bits); # 将索引数组转为字节数组:=[0..256]{5} $activeCode = new ActiveCode(); # 创建对象 $activeCode->plat = $by8bits[1]; # 第一个字节: 平台 $activeCode->package = $by8bits[3]; # 第二个字节: 礼包编号 $i = 0; # 临时变量 $i += ($by8bits[0] ^ $by8bits[3] ^ $by8bits[1]); # 剩余字节为兑换码的编号, 低8位 $i += ( $by8bits[4] ^ $by8bits[3] ^ $by8bits[1] ) << 8; # 高8位 $i += ($by8bits[2] ^ $by8bits[3] ^ $by8bits[1] ) << 16; # 第17-24位 $i += ($by8bits[5] ^ $by8bits[3] ^ $by8bits[1] ) << 24; # 第25-32位 $i = self::uint32val($i); # 提取编号(32位环境,大int值会转为float进行运算) $i = 4294967295 - $i; # 补码才是真正的编号 $i /= 85889; # 编号再除以一个特殊值才还原为最终编号 if (intval($i) - $i == 0) { # 确认是合法整数 $activeCode->number = intval($i); } return $activeCode; } } /** * php本身没有unint类型, 网上找的,具体代码看不懂--gwang * @param type $var * @return type */ static function uint32val($var) { if (is_string($var)) { # 字符串 if (PHP_INT_MAX > 2147483647) { # 大于32位 $var = intval($var); } else { # 利用float来避免数值较大时损失高位信息 $var = floatval($var); } } if (!is_int($var)) { $var = intval($var); # 再次强转int } if ((0 > $var) || ($var > 4294967295)) { $var &= 4294967295; # uint32最大值 if (0 > $var) { $var = sprintf('%u', $var); # 转为uint(string) } } return $var; } /** * 转换 10个 5bit Bytes 到 6个 8bit Bytes * @param array $data 长度不小于10的字节数组 * @return array */ static function fetch5BitByte($data) { $ret5 = array(); $ret5[0] = ( $data[0] + intval(( $data[1] & 0x7) << 5)); # 5 + 3 = 8 $ret5[1] = ( intval(($data[1] & 0x18 ) >> 3) # 2 + 5 + 1 = 8 + intval($data[2] << 2) + intval(($data[3] & 0x1) << 7)); $ret5[2] = ( intval(($data[3] & 0x1E) >> 1) # 4 + 4 = 8 + intval(($data[4] & 0xf) << 4)); $ret5[3] = ( intval(($data[4] & 0x10) >> 4) # 1 + 5 + 2 = 8 + intval($data[5] << 1) + intval(($data[6] & 0x3) << 6)); $ret5[4] = ( intval(($data[6] & 0x1C) >> 2) + intval($data[7] << 3)); # 3 + 5 = 8 $ret5[5] = ( intval(($data[8]) + intval($data[9] << 5))); # 5 + 3 = 8 return $ret5; } }