= 224) { $bits = 3; $count++; //第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符 } elseif ($c >= 192) { $count++; $bits = 2; //否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号) } else { $bits = 1; $count += 0.5; } } $slen = $slen + $bits; $i = $i + $bits; } return substr($string, 0, $slen) . $ext; } //计算文字字数,二个字母当一个汉字 static function getWordNum($string, $code = 'utf-8') { $i = 0; //开始字节数 $count = 0; //开始字数 if ($code == 'utf-8') { //utf-8编码 while (isset($string[$i]) && ord($string[$i]) != 0) { //还没有到结尾 $b = ord($string[$i]); //第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符 if ($b >= 224) { $i += 3; $count++; //第一个字节大于192小于224的,它与它之后的1个字节组成一个UTF-8字符 } elseif ($b >= 192) { $i += 2; $count++; //否则第一个字节本身就是一个英文字符(包括数字和一小部分标点符号) } else { $i += 1; $count += 0.5; } } return ceil($count); } //gkb编码 while (isset($string[$i]) && ord($string[$i]) != 0) { $b = ord($string[$i]); //第一个字节ASCII码>129的,它与它之后的1个字节一起组成一个gbk字符。 if ($b > 129) { $i += 2; $count++; //第一个字节ASCII码<=129的,一个字节组成一个gbk字符。 } else { $i++; $count += 0.5; } } return ceil($count); } /* * 取汉字拼音首字母 */ static function getfirstchar($s0) { $fchar = ord($s0{0}); if ($fchar >= ord("A") and $fchar <= ord("z")) return strtoupper($s0{0}); $s1 = iconv("UTF-8", "gb2312", $s0); $s2 = iconv("gb2312", "UTF-8", $s1); if ($s2 == $s0) { $s = $s1; } else { $s = $s0; } $asc = ord($s{0}) * 256 + ord($s{1}) - 65536; if ($asc >= -20319 and $asc <= -20284) return "A"; if ($asc >= -20283 and $asc <= -19776) return "B"; if ($asc >= -19775 and $asc <= -19219) return "C"; if ($asc >= -19218 and $asc <= -18711) return "D"; if ($asc >= -18710 and $asc <= -18527) return "E"; if ($asc >= -18526 and $asc <= -18240) return "F"; if ($asc >= -18239 and $asc <= -17923) return "G"; if ($asc >= -17922 and $asc <= -17418) return "H"; if ($asc >= -17417 and $asc <= -16475) return "J"; if ($asc >= -16474 and $asc <= -16213) return "K"; if ($asc >= -16212 and $asc <= -15641) return "L"; if ($asc >= -15640 and $asc <= -15166) return "M"; if ($asc >= -15165 and $asc <= -14923) return "N"; if ($asc >= -14922 and $asc <= -14915) return "O"; if ($asc >= -14914 and $asc <= -14631) return "P"; if ($asc >= -14630 and $asc <= -14150) return "Q"; if ($asc >= -14149 and $asc <= -14091) return "R"; if ($asc >= -14090 and $asc <= -13319) return "S"; if ($asc >= -13318 and $asc <= -12839) return "T"; if ($asc >= -12838 and $asc <= -12557) return "W"; if ($asc >= -12556 and $asc <= -11848) return "X"; if ($asc >= -11847 and $asc <= -11056) return "Y"; if ($asc >= -11055 and $asc <= -10247) return "Z"; return null; } /** * 取汉字拼音首字母 * @param unknown_type $zh * @return string */ function getSpelling($zh) { $zh = str_replace('圳', 'z', $zh); $ret = ""; $s1 = iconv("UTF-8", "gb2312", $zh); $s2 = iconv("gb2312", "UTF-8", $s1); if ($s2 == $zh) { $zh = $s1; } for ($i = 0; $i < strlen($zh); $i++) { $s1 = substr($zh, $i, 1); $p = ord($s1); if ($p > 160) { $s2 = substr($zh, $i++, 2); $ret .= self::getfirstchar($s2); } else { $ret .= $s1; } } return strtolower($ret); } /* * 取随机数 */ static function charsShuffle($length) { $str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $key = ''; for ($i = 0; $i < $length; $i++) { $pos = mt_rand(0, strlen($str) - 1); $key .= $str[$pos]; } return $key; } /* * 取随机数(小写) */ static function charsShuffleLowerCase($length) { $str = 'abcdefghijklmnopqrstuvwxyz0123456789'; $key = ''; for ($i = 0; $i < $length; $i++) { $pos = mt_rand(0, strlen($str) - 1); $key .= $str[$pos]; } return $key; } /** * 随机取数字 * @return unknown */ static function getRandNum($num) { $shuffle = str_shuffle('1234567890'); $number = substr($shuffle, 0, $num); return $number; } // $string: 明文 或 密文 // $operation:DECODE表示解密,其它表示加密 // $key: 密匙 // $expiry:密文有效期 public function authcode($string, $operation = 'DECODE', $expiry = 0) { // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 $ckey_length = 4; // 密匙 $key = md5(self::KEY); // 密匙a会参与加解密 $keya = md5(substr($key, 0, 16)); // 密匙b会用来做数据完整性验证 $keyb = md5(substr($key, 16, 16)); // 密匙c用于变化生成的密文 $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; // 参与运算的密匙 $cryptkey = $keya . md5($keya . $keyc); $key_length = strlen($cryptkey); // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性 // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; $string_length = strlen($string); $result = ''; $box = range(0, 255); $rndkey = array(); // 产生密匙簿 for ($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($cryptkey[$i % $key_length]); } // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度 for ($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } // 核心加解密部分 for ($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; // 从密匙簿得出密匙进行异或,再转成字符 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if ($operation == 'DECODE') { // substr($result, 0, 10) == 0 验证数据有效性 // substr($result, 0, 10) - time() > 0 验证数据有效性 // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性 // 验证数据有效性,请看未加密明文的格式 if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) { return substr($result, 26); } else { return ''; } } else { // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 return $keyc . str_replace('=', '', base64_encode($result)); } } /** * 返回8位随机字符,重复概率较低 */ public static function getRandStr($id = null) { $chars = "0123456789abcdefghijklmnopqrstuvwxyz"; $res = ""; for ($i = 0; $i < 8; $i++) { $res .= $chars[mt_rand(0, strlen($chars) - 1)]; } $rand = empty($id) ? $res : $res . $id; return $rand; } public static function randIP() { $arr_1 = array("218", "218", "66", "66", "218", "218", "60", "60", "202", "204", "66", "66", "66", "59", "61", "60", "222", "221", "66", "59", "60", "60", "66", "218", "218", "62", "63", "64", "66", "66", "122", "211"); $randarr = mt_rand(0, count($arr_1)); $ip1id = $arr_1[$randarr]; $ip2id = round(rand(600000, 2550000) / 10000); $ip3id = round(rand(600000, 2550000) / 10000); $ip4id = round(rand(600000, 2550000) / 10000); return $ip1id . "." . $ip2id . "." . $ip3id . "." . $ip4id; } //写日志 public static function log($content, $file) { $content .= "\r\n"; $fh = fopen($file, 'ab'); //打开,追加模式 fwrite($fh, $content); fclose($fh); } //减法 public static function calcSub($a, $b) { return ($a * 1000 - $b * 1000) / 1000; } //加法 public static function calcAdd($a, $b) { return ($a * 1000 + $b * 1000) / 1000; } public static function ride($a, $b) { } /** * 生成商家提现需要使用的订单号 */ public static function generateMerchantCashOrderNo($merchantId) { return "C" . date('ymdHis') . $merchantId . mt_rand(10000, 99999); } /** * 生成用户需要使用的订单号 * shish 2019.4.20 * id 不小于8位的用户id */ public static function generateOrderNo($merchantId, $userId) { $userId = empty($userId) ? rand(12013120, 12536120) : $userId; if (strlen($userId) < 8) { exit('用户ID少于8位数'); } $no = date('ymdHis') . $merchantId . $userId . mt_rand(10000, 99999); if (strlen($no) > 32) { exit('订单位数大于32位'); } return $no; } //微信32位的场景ID shish 2019.9.4 public static function generateSceneId($merchantId) { $no = 'S' . date('YmdHis') . $merchantId . mt_rand(100000, 999999); if (strlen($no) > 32) { $no = substr($no, 0, 32); } return $no; } //将加密窜转成可以在http上传输的字符 public static function urlSafeB64Encode($string) { $data = base64_encode($string); $data = str_replace(array('+', '/', '='), array('-', '_', ''), $data); return $data; } //将url上传输的字符解密 public static function urlSafeBase64Decode($string) { $data = str_replace(array('-', '_'), array('+', '/'), $string); $mod4 = strlen($data) % 4; if ($mod4) { $data .= substr('====', $mod4); } return base64_decode($data); } //中文二边保留,中间用*号代替 shish 2019.8.13 public static function replaceXH($name) { //获取字符串长度 $strlen = mb_strlen($name, 'utf-8'); //如果字符创长度小于2,不做任何处理 if ($strlen < 2) { return $name; } else { //mb_substr — 获取字符串的部分 $firstStr = mb_substr($name, 0, 1, 'utf-8'); $lastStr = mb_substr($name, -1, 1, 'utf-8'); //str_repeat — 重复一个字符串 return $strlen == 2 ? $firstStr . str_repeat('*', mb_strlen($name, 'utf-8') - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr; } } //生成唯一的文件名称 shish 2020.1.7 public static function uniqueFileName() { //参考 https://www.cnblogs.com/yjf512/p/9057229.html //https://www.cnblogs.com/roluce/p/6026081.html return md5(uniqid(mt_rand(), true)); } //生成短的随机名称,基于当前时间微秒数 shish 2020.4.13 public static function shortUniqueId($id) { //示例:05e946fc1008bc return uniqid($id); } }