|
|
@@ -6,432 +6,441 @@ use Yii;
|
|
|
|
|
|
class stringUtil
|
|
|
{
|
|
|
+
|
|
|
+ const KEY = 'Aos4eLEmqpo8dmJleG610tR1KxUVQ5OzgkzpYM23PLqwSaU3Io';
|
|
|
+
|
|
|
+ //随机编号,英文开头,用于鲜花商品编号
|
|
|
+ public static function buildRandNo($id)
|
|
|
+ {
|
|
|
+ return 'F' . $id . time();// F == flower
|
|
|
+ }
|
|
|
+
|
|
|
+ //创建微信Token使用
|
|
|
+ public static function buildWxToken($id)
|
|
|
+ {
|
|
|
+ return 'wt' . $id . time();
|
|
|
+ }
|
|
|
+
|
|
|
+ //订单号,用于购买商品生成的订单等
|
|
|
+ public static function buildOrderNo($id = 0)
|
|
|
+ {
|
|
|
+ mt_srand((double)microtime() * 1000000);
|
|
|
+ $no = empty($id) ? '' : $id;
|
|
|
+ $no .= date('ymdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
|
|
|
+ return $no;
|
|
|
+ }
|
|
|
+
|
|
|
+ //判断是否手机号
|
|
|
+ public static function isMobile($no)
|
|
|
+ {
|
|
|
+ return preg_match("/^1[0-9]\d{9}$/", $no) == true ? true : false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static function isEmail($email)
|
|
|
+ {
|
|
|
+ $reg = '/\w+@\w+(?:\.\w+){1,3}/i';
|
|
|
+ if (preg_match($reg, $email)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- const KEY = 'Aos4eLEmqpo8dmJleG610tR1KxUVQ5OzgkzpYM23PLqwSaU3Io';
|
|
|
-
|
|
|
- //随机编号,英文开头,用于鲜花商品编号
|
|
|
- public static function buildRandNo($id)
|
|
|
- {
|
|
|
- return 'F' . $id . time();// F == flower
|
|
|
- }
|
|
|
-
|
|
|
- //创建微信Token使用
|
|
|
- public static function buildWxToken($id)
|
|
|
- {
|
|
|
- return 'wt' . $id . time();
|
|
|
- }
|
|
|
-
|
|
|
- //订单号,用于购买商品生成的订单等
|
|
|
- public static function buildOrderNo($id = 0)
|
|
|
- {
|
|
|
- mt_srand((double)microtime() * 1000000);
|
|
|
- $no = empty($id) ? '' : $id;
|
|
|
- $no .= date('ymdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
|
|
|
- return $no;
|
|
|
- }
|
|
|
-
|
|
|
- //判断是否手机号
|
|
|
- public static function isMobile($no)
|
|
|
- {
|
|
|
- return preg_match("/^1[0-9]\d{9}$/", $no) == true ? true : false;
|
|
|
- }
|
|
|
-
|
|
|
- public static function isEmail($email)
|
|
|
- {
|
|
|
- $reg = '/\w+@\w+(?:\.\w+){1,3}/i';
|
|
|
- if (preg_match($reg, $email)) {
|
|
|
- return true;
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- static function subStringUtf8($string, $length, $ext = '')
|
|
|
- {
|
|
|
- $num = self::getWordNum($string);
|
|
|
- //echo $num;exit();
|
|
|
- //如果截取字数大于字符长度
|
|
|
- if ($num <= $length) {
|
|
|
- return $string;
|
|
|
- }
|
|
|
-
|
|
|
- $str_length = $length * 3; //总的字节数
|
|
|
- $slen = 0;
|
|
|
- $i = 0;
|
|
|
- $count = 0;
|
|
|
- while ($i <= $str_length && $count < $length) {
|
|
|
- if (isset($string[$i])) {
|
|
|
- $c = ord($string[$i]);
|
|
|
- //第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
|
|
|
- if ($c >= 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);
|
|
|
- }
|
|
|
+ //是否所有都是英文字母 shish 2021.1
|
|
|
+ public static function isLetter()
|
|
|
+ {
|
|
|
+ if (preg_match("/^[a-zA-Z\s]+$/", $str)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
+ static function subStringUtf8($string, $length, $ext = '')
|
|
|
+ {
|
|
|
+ $num = self::getWordNum($string);
|
|
|
+ //echo $num;exit();
|
|
|
+ //如果截取字数大于字符长度
|
|
|
+ if ($num <= $length) {
|
|
|
+ return $string;
|
|
|
+ }
|
|
|
+
|
|
|
+ $str_length = $length * 3; //总的字节数
|
|
|
+ $slen = 0;
|
|
|
+ $i = 0;
|
|
|
+ $count = 0;
|
|
|
+ while ($i <= $str_length && $count < $length) {
|
|
|
+ if (isset($string[$i])) {
|
|
|
+ $c = ord($string[$i]);
|
|
|
+ //第一个字节大于224的,它与它之后的2个字节一起组成一个UTF-8字符
|
|
|
+ if ($c >= 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);
|
|
|
+ }
|
|
|
+
|
|
|
//参数格式化,错误提示查看友好 shish 2021.01.04
|
|
|
public static function paramsFriend($params)
|
|
|
{
|
|
|
@@ -445,5 +454,5 @@ class stringUtil
|
|
|
$str .= "\n]";
|
|
|
return $str;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|