| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 |
- <?php
- /**
- * 通用函数库.
- *
- * @author nj <nj@gmail.com>
- * @date 2019-11-01 14:42:37
- */
- declare(strict_types=1);
- use App\Repositories\Service\CommonService;
- use App\Repositories\Utils\M3u8CacheRepository;
- use Hashids\Hashids;
- /**
- * 获取分页start offset
- * @param $amount
- * @param int $page
- * @param int $page_size
- * @return int|mixed
- */
- function get_page_start($amount, $page = 1, $page_size = 20)
- {
- if (empty($amount)) {
- return $page_size;
- }
- $page_size = empty($page_size) ? 20 : $page_size;
- $page_most = ceil($amount / $page_size);
- if (isset($page)) {
- $page = intval($page);
- if ($page > $page_most) {
- $page = $page_most;
- }
- } else {
- $page = 1;
- }
- $page = max(1, $page); // 找出最大值.
- $start_limit = ($page - 1) * $page_size;
- return intval($start_limit);
- }
- /**
- * 格式化页码入参
- * @param $page
- * @return int
- */
- function format_page($page)
- {
- $page = intval($page);
- if ($page <= 0) {
- $page = 1;
- }
- if ($page > PHP_INT_MAX) {
- $page = PHP_INT_MAX;
- }
- return $page;
- }
- /**
- * 密码星号加密
- * @param string $str 输入的字符串
- * @return string
- */
- function pass_encode($str)
- {
- $len = strlen($str);
- if ($len < 1) {
- return '';
- }
- $new = '';
- for ($i = 0; $i < $len; $i++) {
- $new .= ($i == 0 || $i == $len - 1) ? $str[$i] : '*';
- }
- return $new;
- }
- /**
- * 密码星号解密
- * @param string $new 明文密码
- * @param string $old 原始密码
- * @return mixed
- */
- function pass_decode($new, $old)
- {
- return $new == pass_encode($old) ? $old : $new;
- }
- /**
- * 加密手机号
- * @param $mobile
- * @return string
- */
- function encode_mobile($mobile)
- {
- $str = '';
- if ($mobile) {
- $len = strlen($mobile);
- for ($i = 0; $i < $len; $i++) {
- $str .= ($i < 5 || $i > $len - 4) ? $mobile[$i] : '*';
- }
- }
- return $str;
- }
- /**
- * 更新OpCache
- * 生成缓存php文件的地方都需要调用此函数
- * @return void
- */
- function opcache_update()
- {
- if (function_exists('opcache_reset')) {
- opcache_reset();
- }
- }
- /**
- * 获取相对依赖双斜杠开头的URL地址
- * @param $url
- * @return mixed
- */
- function get_slashes_url($url)
- {
- if (preg_match('/^(http|https)\:\/\/(.*?)$/i', $url, $arr_matches)) {
- return '//' . $arr_matches[2];
- } else {
- return $url;
- }
- }
- /**
- * json响应成功
- * @param mixed $data 数据
- * @param string $message 消息
- * @return mixed
- */
- function json_success($data, $message = '操作成功')
- {
- $handshake = '';
- $isValidMg = false;
- if (class_exists('\Modules\Manage\Services\AuthService')) {
- $service = make(\Modules\Manage\Services\AuthService::class);
- // 如果有效后台header,则直接不加密,进行明文通讯.
- $isValidMg = $service->checkValidMgHeaderHandShake();
- }
- if (!$isValidMg) {
- $handshake = \App\Constants\CommonConstant::getHandShake();
- if (!empty($handshake)) {
- $inputData = request()->all();
- $inputHandShake = $inputData['handshake'] ?? $handshake;
- $arrMap = \App\Constants\CommonConstant::getHandSnakeKey($inputHandShake);
- // $arrMap = \App\Constants\CommonConstant::getHandSnakeKey($handshake);
- $data = hand_encrypt(json_encode($data), $arrMap['key'], '');
- $handshake = $inputHandShake;
- }
- }
- $res = [
- 'code' => 200,
- 'message' => $message,
- 'data' => $data,
- 'handshake' => $handshake,
- ];
- return response()->json($res);
- }
- /**
- * json响应失败
- * @param string $message 消息
- * @param int $code 代码
- * @return mixed
- */
- function json_fail($message, $code = 500, $data = [])
- {
- $handshake = '';
- $isValidMg = false;
- if (class_exists('\Modules\Manage\Services\AuthService')) {
- $service = make(\Modules\Manage\Services\AuthService::class);
- // 如果有效后台header,则直接不加密,进行明文通讯.
- $isValidMg = $service->checkValidMgHeaderHandShake();
- }
- if (!$isValidMg) {
- $handshake = \App\Constants\CommonConstant::getHandShake();
- if (!empty($handshake)) {
- $inputData = request()->all();
- $inputHandShake = $inputData['handshake'] ?? $handshake;
- $arrMap = \App\Constants\CommonConstant::getHandSnakeKey($inputHandShake);
- // $arrMap = \App\Constants\CommonConstant::getHandSnakeKey($handshake);
- if (!empty($data)) {
- $data = hand_encrypt($data, $arrMap['key'], '');
- } else {
- $data = '';
- }
- $handshake = $inputHandShake;
- }
- }
- $res = [
- 'code' => $code,
- 'message' => $message,
- 'data' => $data,
- 'handshake' => $handshake,
- ];
- return response()->json($res);
- }
- function json_stock_fail($message, $code = 500)
- {
- $res = [
- 'code' => $code,
- 'message' => $message,
- ];
- // return json_encode($res);
- $result = '';
- $handshake = \App\Constants\CommonConstant::getHandShake();
- $handshake = 'prod';
- if (!empty($handshake)) {
- $key = \App\Constants\CommonConstant::getStockHandSnakeKey();
- $result = hand_encrypt($res, $key, '');
- }
- return $result;
- }
- function json_stock_success($data, $message = '成功')
- {
- $res = [
- 'code' => 200,
- 'result' => $data,
- 'message' => $message
- ];
- // return json_encode($res);
- $result = '';
- $handshake = \App\Constants\CommonConstant::getHandShake();
- $handshake = 'prod';
- if (!empty($handshake)) {
- $key = \App\Constants\CommonConstant::getStockHandSnakeKey();
- $result = hand_encrypt($res, $key, '');
- }
- return $result;
- }
- /**
- * 随机生成指定长度字符串
- * @param int $len 长度
- * @return string
- */
- function rand_letter($len = 18)
- {
- $str = '';
- if ($len <= 0) {
- $len = 18;
- }
- $chars = "abcdefhjmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWYXZ";
- $clen = strlen($chars);
- $max = $clen - 1;
- for ($i = 0; $i < $len; $i++) {
- $str .= $chars[mt_rand(0, $max)];
- }
- return $str;
- }
- /**
- * 随机生成字符串
- * @param int $length 长度
- * @param int $numeric 纯数字
- * @return string
- */
- function random($length, $numeric = 0)
- {
- if (version_compare(PHP_VERSION, '4.2.0', '<')) {
- mt_srand((double)microtime() * 1000000);
- } else {
- mt_srand();
- }
- $seed = base_convert(md5(mt_rand(1, 9) . microtime()), 16, $numeric ? 10 : 35);
- $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed));
- $hash = '';
- $max = strlen($seed) - 1;
- for ($i = 0; $i < $length; $i++) {
- $hash .= $seed[mt_rand(0, $max)];
- }
- return $hash;
- }
- /**
- * AES 加密
- * @param mixed $content 明文
- * @param string $key 密钥
- * @param string $iv 向量,必须为数字
- * @param string $cipher 算法.
- * @param int $option 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2.
- * @return string
- */
- function aes_encrypt($content, $key, $iv = '', $cipher = 'AES-256-CBC', $option = 1)
- {
- $ivLength = openssl_cipher_iv_length($cipher); // 向量长度.
- /*$iv = openssl_random_pseudo_bytes($ivLength); // 根据长度生成向量.*/
- //$option = OPENSSL_RAW_DATA; // 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2.
- $tag = null; // 使用 AEAD 密码模式(GCM 或 CCM)时传引用的验证标签.
- $aad = ''; // 附加的验证数据.
- $tagLength = 16; // 验证 tag 的长度。GCM 模式时,它的范围是 4 到 16.
- $iv = (string)$iv;
- return @openssl_encrypt($content, $cipher, $key, $option, $iv);
- }
- /**
- * AES 解密
- * @param string $content base64密文
- * @param string $key 密钥
- * @param string $iv 向量,必须为数字
- * @param string $cipher 算法.
- * @param int $option 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2.
- * @return string
- */
- function aes_decrypt($content, $key, $iv = '', $cipher = 'AES-256-CBC', $option = 1)
- {
- $iv = (string)$iv;
- return @openssl_decrypt($content, $cipher, $key, $option, $iv);
- }
- /**
- * 通讯握手加密.
- * @param $content
- * @param $key
- * @param string $iv 向量,必须为数字
- * @return string
- */
- function hand_encrypt($content, $key, $iv = ''): string
- {
- $cipher = 'AES-128-ECB';
- if (is_array($content)) {
- $content = json_encode($content, JSON_UNESCAPED_UNICODE);
- }
- return base64_encode(aes_encrypt($content, $key, $iv, $cipher, 1));
- }
- /**
- * 通信握手解密.
- * @param $content
- * @param $key
- * @param string $iv 向量,必须为数字
- * @return false|string
- */
- function hand_decrypt($content, $key, $iv = '')
- {
- $cipher = 'AES-128-ECB';
- $content = base64_decode($content);
- return aes_decrypt($content, $key, $iv, $cipher, 1);
- }
- /**
- * 获取Request解密数据.
- * @return array|mixed
- */
- function getDecodeData()
- {
- $isValidMg = false;
- if (class_exists('\Modules\Manage\Services\AuthService')) {
- $service = make(\Modules\Manage\Services\AuthService::class);
- // 如果有效后台header,则直接不加密,进行明文通讯.
- $isValidMg = $service->checkValidMgHeaderHandShake();
- }
- $inputData = request()->all();
- if (!$isValidMg) {
- // 先拿系统里当前flag.
- $handshake = \App\Constants\CommonConstant::getHandShake();
- if (!empty($handshake)) {
- $allowShake = \App\Constants\CommonConstant::allowHandShakeKeys();
- $inputHandShake = $inputData['handshake'] ?? random(7);
- if (!array_key_exists($inputHandShake, $allowShake) || empty($inputHandShake)) {
- throw new \App\Exception\ApiException('在天愿作比翼鸟,在地愿为连理枝');
- }
- // if ($inputHandShake != $handshake) {
- // throw new \App\Exception\ApiException('在天愿作比翼鸟,在地愿为连理枝');
- // }
- $originData = $inputData['data'] ?? '';
- if (!is_string($originData)) {
- throw new \App\Exception\ApiException('数据格式有误1');
- }
- $arrMap = \App\Constants\CommonConstant::getHandSnakeKey($inputHandShake);
- try {
- $data = !empty($originData) ? json_decode(hand_decrypt($originData, $arrMap['key'], ''), true) : [];
- } catch (\Throwable $exception) {
- throw new \App\Exception\ApiException('数据格式有误2');
- }
- } else {
- $data = $inputData['data'] ?? [];
- }
- } else {
- $data = $inputData['data'] ?? [];
- }
- return $data;
- }
- /**
- * 过滤数据
- * @param $data - 1维数据
- * @return array
- * @tutorial 若数组值不是空长度则保留,反之就清除过滤
- */
- function action_data($data = array())
- {
- if (!$data) {
- return $data;
- }
- foreach ($data as $k => $v) {
- if (mb_strlen((string)$v) < 1) {
- unset($data[$k]);
- }
- }
- return $data;
- }
- /**
- * 加密ID.
- * @param $id
- * @param int $length 长度
- * @return string
- */
- function hashEncodeId($id, $length = 6)
- {
- $hashids = new Hashids(config('hashids.salt', ''), 6);
- return $hashids->encode($id);
- }
- /**
- * 解密ID.
- * @param $str
- * @return string
- */
- function hashDecodeId($str)
- {
- $hashids = new Hashids(config('hashids.salt', ''), 6);
- $arr = $hashids->decode($str);
- return implode('', $arr);
- }
- /**
- * 权重计算
- *
- * @param $data
- * @return mixed
- */
- function countWeight($data)
- {
- $temp = [];
- foreach ($data as $v) {
- if (isset($v->weights)) {
- for ($i = 0; $i < $v->weights; $i++) {
- $temp[] = $v;//放大数组
- }
- } else {
- for ($i = 0; $i < $v['weights']; $i++) {
- $temp[] = $v;//放大数组
- }
- }
- }
- $num = count($temp); //查看网上的有错误,本人已改正
- $int = mt_rand(0, $num - 1);//获取一个随机数
- $result = $temp[$int];
- return $result; //返回一维数组
- }
- /**
- * 凯撒对称加密核心算法
- * @param string $str 字符串源
- * @param string $type 类型,encode=加密,decode=解密
- * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开
- * @param int $offset 偏移
- * @return string
- */
- function caesar_cipher($str, $type = 'encode', $scale = 'c,l,n', $offset = 3)
- {
- if (empty($str)) {
- return '';
- }
- if (!$offset) {
- // 无偏移, 直接返回原来的字符串
- return $str;
- }
- if (empty($scale)) {
- $scale = 'c,l,n';
- }
- if ($type == 'decode') {
- // 解密反向偏移
- $offset = -$offset;
- }
- $func = function ($match, $offset, $start, $end) {
- $min = ord($start);
- $max = ord($end);
- $flag_old = ord($match);
- $flag = $flag_old + $offset;
- if ($offset > 0) {
- if ($flag > $max) {
- $flag -= ($max - $min) + 1;
- }
- } elseif ($offset < 0) {
- if ($flag < $min) {
- $flag += ($max - $min) + 1;
- }
- }
- return chr($flag);
- };
- $arr_scale = explode(',', $scale); //允许的范围转换成数组,方便判断
- $pattern = '/[\x{4e00}-\x{9fbb}a-zA-Z0-9]/u';
- $result = preg_replace_callback(
- $pattern,
- function ($matches) use ($offset, $arr_scale, $func) {
- $str = $match = $matches[0];
- if (preg_match('/[\x{4e00}-\x{9fbb}]/u', $match)) {
- // 汉字
- if (in_array('c', $arr_scale)) {
- $min = intval(hexdec(unpack("H6codes", "一")['codes']));
- $max = intval(hexdec(unpack("H6codes", "龻")['codes']));
- $arr_hex = unpack("H6codes", $match);
- $zi_hex = $arr_hex['codes'];
- $zi_dec = intval(hexdec($zi_hex));
- $flag = $zi_dec + $offset;
- if ($offset > 0) {
- if ($flag > $max) {
- $flag -= ($max - $min) + 1;
- }
- } elseif ($offset < 0) {
- if ($flag < $min) {
- $flag += ($max - $min) + 1;
- }
- }
- $str_hex = dechex($flag);
- $str = pack("H". strlen($str_hex), $str_hex);
- }
- } elseif (preg_match('/[0-9]/', $match)) {
- // 数字
- if (in_array('n', $arr_scale)) {
- $str = $func($match, $offset, '0', '9');
- }
- } elseif (preg_match('/[a-z]/', $match)) {
- // 小写字母
- if (in_array('l', $arr_scale)) {
- $str = $func($match, $offset, 'a', 'z');
- }
- } elseif (preg_match('/[A-Z]/', $match)) {
- // 大写字母
- if (in_array('l', $arr_scale)) {
- $str = $func($match, $offset, 'A', 'Z');
- }
- }
- return $str;
- },
- $str
- );
- return $result;
- }
- /**
- * 凯撒对称加密
- * @param string $str 字符串源
- * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开
- * @param int $offset 偏移
- * @return string
- */
- function caesar_encode($str, $scale = 'c,l,n', $offset = 3)
- {
- return caesar_cipher($str, 'encode', $scale, $offset);
- }
- /**
- * 凯撒对称解密
- * @param string $str 字符串源
- * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开
- * @param int $offset 偏移
- * @return string
- */
- function caesar_decode($str, $scale = 'c,l,n', $offset = 3)
- {
- return caesar_cipher($str, 'decode', $scale, $offset);
- }
- /**
- * 处理异常时间的问题(如2022-02-31)
- *
- * @param $date
- * @return bool
- */
- function checkmydate($date) {
- $tempDate = explode('-', $date);
- return checkdate((int)$tempDate[1], (int)$tempDate[2], (int)$tempDate[0]);
- }
- /**
- * 处理结构体
- *
- * @param $message
- * @return mixed
- */
- function structureHandle(string $content, string $msgType)
- {
- $content = json_decode($content, true);
- switch ($msgType) {
- case 'text':
- $content['text'] = make(CommonService::class)->filterString($content['text']);
- break;
- case 'image':
- case 'file':
- case 'audio':
- $content['url'] = M3u8CacheRepository::getImageUrl($content['url']);
- break;
- case 'media':
- $content['url'] = M3u8CacheRepository::getVideoInnerUrl($content['url']);
- $content['cover'] = M3u8CacheRepository::getImageUrl($content['cover']);
- }
- return $content;
- }
- /**
- * 计算两个日期相隔多少年,多少月,多少天
- *
- * @param $startDate
- * @param $endData
- * @return array
- * @throws Exception
- */
- function diffDate($startDate, $endData)
- {
- $datetime1 = new \DateTime($startDate);
- $datetime2 = new \DateTime($endData);
- $interval = $datetime1->diff($datetime2);
- $time['y'] = $interval->format('%Y');
- $time['m'] = $interval->format('%m');
- $time['d'] = $interval->format('%d');
- return $time;
- }
- /**
- * 检测支付链接协议
- *
- * @param $payUrl
- * @return mixed|string
- */
- function checkPayUrl($payUrl) {
- if (strpos($payUrl, 'alipays://') !== false) {
- $payUrl = 'https://r.tool.py163.xyz/dk.html?_r_=' . urlencode($payUrl);
- }
- return $payUrl;
- }
- function truncateText($text, $max_length = 100, $suffix = '...') {
- if (mb_strlen($text, 'UTF-8') <= $max_length) {
- return $text;
- }
- return mb_substr($text, 0, $max_length, 'UTF-8') . $suffix;
- }
|