[update] Version 0.6.0

This commit is contained in:
lkeme 2020-07-30 19:20:11 +08:00
parent 8a38ad85a8
commit 962b7d46a3
14 changed files with 538 additions and 63 deletions

View File

@ -1,6 +1,20 @@
# Release Notes
# 本项目Log
## v0.6.0.200730 alpha (2020-07-30)
### Added
- 添加小心心支持
-
### Changed
- 更新天选过滤关键词
-
### Fixed
- 修复节奏风暴逻辑错误
-
## v0.5.0.200625 alpha (2020-06-25)
### Added

55
DOC.md
View File

@ -2,7 +2,7 @@
<p align="center"><img width="300px" src="https://i.loli.net/2018/04/20/5ad97bd395912.jpeg"></p>
<p align="center">
<img src="https://img.shields.io/badge/version-0.5.0.200625 alpha-green.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/version-0.6.0.200730 alpha-green.svg?longCache=true&style=for-the-badge">
<img src="https://img.shields.io/badge/license-mit-blue.svg?longCache=true&style=for-the-badge">
</p>
@ -15,32 +15,33 @@ B 站直播实用脚本
|plugin |version |description |
|--------------------|--------------------|--------------------|
|Login |20.06.24 |账号登录 |
|Schedule |20.06.24 |休眠控制 |
|MasterSite |20.06.24 |主站助手 |
|Daily |20.06.24 |每日礼包 |
|Heart |20.06.24 |双端心跳 |
|Task |20.06.24 |每日任务 |
|Silver |20.06.24 |银瓜子宝箱 |
|Barrage |20.06.24 |活跃弹幕 |
|Silver2Coin |20.06.24 |银瓜子换硬币 |
|GiftSend |20.06.24 |礼物赠送 |
|Judge |20.06.24 |风纪 |
|GroupSignIn |20.06.24 |友爱社签到 |
|ManGa |20.06.24 |漫画签到分享 |
|Match |20.06.24 |赛事签到分享 |
|GiftHeart |20.06.24 |心跳礼物 |
|MaterialObject |20.06.24 |实物抽奖 |
|AloneTcpClient |20.06.24 |独立监控 |
|ZoneTcpClient |20.06.24 |分区监控 |
|StormRaffle |20.06.24 |节奏风暴 |
|GiftRaffle |20.06.24 |活动礼物 |
|PkRaffle |20.06.24 |大乱斗 |
|GuardRaffle |20.06.24 |舰长总督 |
|AnchorRaffle |20.06.24 |天选时刻 |
|AwardRecord |20.06.24 |获奖通知 |
|Statistics |20.06.24 |数据统计 |
|Competition |20.06.24 |赛事竞猜 |
|Login |20.07.30 |账号登录 |
|Schedule |20.07.30 |休眠控制 |
|MasterSite |20.07.30 |主站助手 |
|Daily |20.07.30 |每日礼包 |
|Heart |20.07.30 |双端心跳 |
|Task |20.07.30 |每日任务 |
|Silver |20.07.30 |银瓜子宝箱 |
|Barrage |20.07.30 |活跃弹幕 |
|Silver2Coin |20.07.30 |银瓜子换硬币 |
|GiftSend |20.07.30 |礼物赠送 |
|Judge |20.07.30 |风纪 |
|GroupSignIn |20.07.30 |友爱社签到 |
|ManGa |20.07.30 |漫画签到分享 |
|Match |20.07.30 |赛事签到分享 |
|GiftHeart |20.07.30 |心跳礼物 |
|MaterialObject |20.07.30 |实物抽奖 |
|AloneTcpClient |20.07.30 |独立监控 |
|ZoneTcpClient |20.07.30 |分区监控 |
|StormRaffle |20.07.30 |节奏风暴 |
|GiftRaffle |20.07.30 |活动礼物 |
|PkRaffle |20.07.30 |大乱斗 |
|GuardRaffle |20.07.30 |舰长总督 |
|AnchorRaffle |20.07.30 |天选时刻 |
|AwardRecord |20.07.30 |获奖通知 |
|Statistics |20.07.30 |数据统计 |
|Competition |20.07.30 |赛事竞猜 |
|SmallHeart |20.07.30 |小心心 |
## 打赏赞助

View File

@ -7,7 +7,7 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交
## 公告
> Currently for Personal Edition **0.5.0.200625 alpha**
> Currently for Personal Edition **0.6.0.200730 alpha**
```notice
---- 免费的东西总是得不到人的珍惜。
@ -28,4 +28,3 @@ Group: [55308141](https://jq.qq.com/?_wv=1027&k=5AIDaJg) | **仅用于BUG提交
## 效果
![](https://i.loli.net/2019/07/13/5d296961a4bae41364.png)

View File

@ -94,6 +94,10 @@ USE_SC=false
SC_KEY=
SC_FILTER_WORDS=
# 小心心|加密服务器(开源)|
USE_HEARTBEAT=true
ENC_SERVER=http://116.85.43.27:3000/enc
#######################
# 房间设置 #
#######################
@ -154,4 +158,4 @@ APP_CALLBACK="http://www.example.com/api.send?text={account}[{level}]: {message}
# WARNING 300
# ERROR 400
#
APP_CALLBACK_LEVEL=400
APP_CALLBACK_LEVEL=400

View File

@ -80,6 +80,7 @@ class App
'GiftSend',
'GroupSignIn',
'GiftHeart',
'SmallHeart',
'MaterialObject',
'AloneTcpClient',
'ZoneTcpClient',

View File

@ -13,7 +13,7 @@ namespace BiliHelper\Core;
class Env
{
private $app_name = 'BiliHelper Personal';
private $app_version = '0.5.0.*';
private $app_version = '0.6.0.*';
/**
* Env constructor.

View File

@ -137,7 +137,14 @@ class AnchorRaffle extends BaseRaffle
'房间抽奖', 'CESHI', 'ceshi', '奖品A', '奖品B', '奖品C', '硬币', '无奖品', '白名单', '我是抽奖',
'0.1', '五毛二', '一分', '一毛', '0.52', '0.66', '0.01', '0.77', '0.16', '照片', '穷', '0.5',
'0.88', '双排', '1毛', '1分', '1角', 'P口罩', '素颜', '写真', '图包', '五毛', '一角', '冥币',
'自拍', '日历', '0.22', '加速器', '越南盾'
'自拍', '日历', '0.22', '加速器', '越南盾','毛','分','限','0.','角','〇点','①元',
'一起玩','不包邮','邮费','续期卡','儿时','闪宠','大师球','一元','两元','两块','赛车',
'代币','一块','一局','好友位','通话','首胜','代金券','辣条','补贴','抵用券','主播素颜照',
'武器箱棺材板','游戏道具','优惠券','日元','发音课','壹元','零点','舰长五折券','上车',
'没有钱','女装','肥宅快乐水','哥斯拉','公主连结','pokemmo','宝可>梦','明日方舟','雪碧','公主连接',
'专属头衔','FF14','韩元','空洞骑士','老婆饼','稀世时装','洛克衣服','帮过图','证件照','自抽号',
'晶耀之星','伊洛纳','.','②元','③元','0·','繁华美化','喵喵喵','闪伊布','①圆','o点','金达摩','嗷呜',
'游戏位','S-追光者','OWL','勾玉','跟yo宝游戏','三元','怡宝','蛋闪迷>你冰','哥伦比亚比索','油条'
];
$custom_words = empty(getenv('ANCHOR_FILTER_WORDS')) ? [] : explode(',', getenv('ANCHOR_FILTER_WORDS'));
$total_words = array_merge($default_words, $custom_words);

View File

@ -180,35 +180,22 @@ class GiftSend
protected static function getMedalList()
{
self::$medal_list = [];
$url = 'https://api.live.bilibili.com/i/api/medal';
$payload = [
'page' => 1,
'pageSize' => 25
];
$data = Curl::get('app', $url, Sign::common($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::warning('获取勋章列表失败!', ['msg' => $data['message']]);
return;
$data = Live::fetchMedalList();
$fans_medals = [];
foreach ($data as $vo) {
if (!isset($vo['roomid'])) continue;
$fans_medals[(string)$vo['roomid']] = $vo;
}
Log::info('勋章列表获取成功!');
if (isset($data['data']['fansMedalList'])) {
$fans_medals = [];
foreach ($data['data']['fansMedalList'] as $vo) {
if (!isset($vo['roomid'])) continue;
$fans_medals[(string)$vo['roomid']] = $vo;
// 基于配置
foreach (self::$room_list as $room_id) {
// 配置是否存在获取
if (!array_key_exists((string)$room_id, $fans_medals)) {
continue;
}
// 基于配置
foreach (self::$room_list as $room_id) {
// 配置是否存在获取
if (!array_key_exists((string)$room_id, $fans_medals)) {
continue;
}
$vo = $fans_medals[(string)$room_id];
// 是否还需要投喂
if ($vo['day_limit'] - $vo['today_feed']) {
self::$medal_list[(string)$vo['roomid']] = ($vo['day_limit'] - $vo['today_feed']);
}
$vo = $fans_medals[(string)$room_id];
// 是否还需要投喂
if ($vo['day_limit'] - $vo['today_feed']) {
self::$medal_list[(string)$vo['roomid']] = ($vo['day_limit'] - $vo['today_feed']);
}
}
}

View File

@ -187,7 +187,7 @@ class Live
*/
public static function webGetRoomInfo($room_id): array
{
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?=23058';
$url = 'https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom';
$payload = [
'room_id' => $room_id
];
@ -266,4 +266,112 @@ class Live
return json_decode($raw, true) ?? ['code' => 404, 'msg' => '上层数据为空!'];
}
}
/**
* @use 获取勋章列表
* @param int $page_size
* @return array
*/
public static function fetchMedalList(int $page_size = 100): array
{
$metal_list = [];
for ($i = 1; $i <= 10; $i++) {
$url = 'https://api.live.bilibili.com/i/api/medal';
$payload = [
'page' => $i,
'pageSize' => $page_size
];
$raw = Curl::get('app', $url, Sign::common($payload));
$de_raw = json_decode($raw, true);
if (isset($data['code']) && $data['code']) {
Log::warning('获取勋章列表失败!', ['msg' => $data['message']]);
return $metal_list;
}
if (empty($de_raw['data']['fansMedalList'])) {
return $metal_list;
}
if (isset($de_raw['data']['fansMedalList'])) {
foreach ($de_raw['data']['fansMedalList'] as $vo) {
array_push($metal_list, $vo);
}
}
if ($de_raw['data']['pageinfo']['totalpages'] == $de_raw['data']['pageinfo']['curPage']) {
return $metal_list;
}
}
Log::info('勋章列表获取成功!');
return $metal_list;
}
/**
* @use 背包获取单项礼物
* @param string $gift_name
* @param int $gift_id
* @return array
*/
public static function fetchBagListByGift(string $gift_name, int $gift_id): array
{
$new_bag_list = [];
$payload = [];
$url = 'https://api.live.bilibili.com/gift/v2/gift/bag_list';
$data = Curl::get('app', $url, Sign::common($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::warning('背包查看失败!', ['msg' => $data['message']]);
return $new_bag_list;
}
if (isset($data['data']['list'])) {
$bag_list = $data['data']['list'];
if (count($bag_list)) {
// 按过期时间 升序
// array_multisort(array_column($bag_list, "gift_id"), SORT_DESC, $bag_list);
array_multisort(array_column($bag_list, "expire_at"), SORT_ASC, $bag_list);
}
foreach ($bag_list as $vo) {
// 去除永久礼物
if ($vo['corner_mark'] == '永久') continue;
if ($vo['gift_id'] == $gift_id && $vo['gift_name'] == $gift_name){
array_push($new_bag_list, $vo);
}
}
}
return $new_bag_list;
}
/**
* @use 赠送礼物
* @param array $guest // 用户信息
* @param array $gift // 礼物信息
* @param int $num // 数量
*/
public static function sendGift(array $guest, array $gift, int $num)
{
$url = 'https://api.live.bilibili.com/gift/v2/live/bag_send';
$user_info = User::parseCookies();
$payload = [
'uid' => $user_info['uid'], // 自己的UID
'gift_id' => $gift['gift_id'],
'ruid' => $guest['uid'], // UP的UID
'send_ruid' => 0,
'gift_num' => $num,
'bag_id' => $gift['bag_id'],
'platform' => 'pc',
'biz_code' => 'live',
'biz_id' => $guest['roomid'], // UP的直播间
'rnd' => time(), // 时间戳
'storm_beat_id' => 0,
'metadata' => '',
'price' => 0,
'csrf' => $user_info['token'],
'csrf_token' => $user_info['token']
];
// {"code":0,"msg":"success","message":"success","data":{"tid":"1595419985112400002","uid":4133274,"uname":"沙奈之朵","face":"https://i2.hdslb.com/bfs/face/eb101ef90ebc4e9bf79f65312a22ebac84946700.jpg","guard_level":0,"ruid":893213,"rcost":30834251,"gift_id":30607,"gift_type":5,"gift_name":"小心心","gift_num":1,"gift_action":"投喂","gift_price":5000,"coin_type":"silver","total_coin":5000,"pay_coin":5000,"metadata":"","fulltext":"","rnd":"1595419967","tag_image":"","effect_block":1,"extra":{"wallet":null,"gift_bag":{"bag_id":210196588,"gift_num":20},"top_list":[],"follow":null,"medal":null,"title":null,"pk":{"pk_gift_tips":"","crit_prob":0},"fulltext":"","event":{"event_score":0,"event_redbag_num":0},"capsule":null},"blow_switch":0,"send_tips":"赠送成功","gift_effect":{"super":0,"combo_timeout":0,"super_gift_num":0,"super_batch_gift_num":0,"batch_combo_id":"","broadcast_msg_list":[],"small_tv_list":[],"beat_storm":null,"smallTVCountFlag":true},"send_master":null,"crit_prob":0,"combo_stay_time":3,"combo_total_coin":0,"demarcation":2,"magnification":1,"combo_resources_id":1,"is_special_batch":0,"send_gift_countdown":6}}
$data = Curl::post('app', $url, Sign::common($payload));
$data = json_decode($data, true);
if (isset($data['code']) && $data['code']) {
Log::warning('送礼失败!', ['msg' => $data['message']]);
} else {
Log::notice("成功向 {$payload['biz_id']} 投喂了 {$num}{$gift['gift_name']}");
}
}
}

View File

@ -296,11 +296,11 @@ class Login
'seccode' => $validate ? "{$validate}|jordan" : '',
'validate' => $validate,
'challenge' => $challenge,
'subid' => 1,
'permission' => 'ALL',
'username' => self::$username,
'password' => self::$password,
'captcha' => '',
'subid' => 1,
'cookies' => ''
];
$raw = Curl::post('app', $url, Sign::login($payload));

301
src/plugin/SmallHeart.php Normal file
View File

@ -0,0 +1,301 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2020 ~ 2021
*/
namespace BiliHelper\Plugin;
use BiliHelper\Core\Log;
use BiliHelper\Core\Curl;
use BiliHelper\Util\TimeLock;
use BiliHelper\Tool\Generator;
class SmallHeart
{
use TimeLock;
private static $enc_server = null; // 加密服务器 配置文件
private static $hb_payload = []; // 心跳请求数据
private static $hb_headers = []; // 心跳请求头
private static $hb_count = 0; // 心跳次数 max 24
private static $hb_room_info = []; // 心跳带勋章房间信息
private static $fans_medals = []; // 全部勋章
private static $grey_fans_medals = []; // 灰色勋章
private static $metal_lock = 0; // 勋章时间锁
public static function run()
{
if (!self::init()) {
return;
}
if (self::$metal_lock < time()) {
self::polishMetal();
self::$metal_lock = time() + 8 * 60 * 60;
}
if (self::getLock() < time()) {
self::heartBeat();
if (self::$hb_count >= 30) {
self::resetVar();
self::setLock(self::timing(2));
} else {
self::setLock(5 * 60);
}
}
}
/**
* @use 重置变量
*/
private static function resetVar()
{
self::$hb_payload = []; // 心跳请求数据
self::$hb_headers = []; // 心跳请求头
self::$hb_count = 0; // 心跳次数 max 24
self::$hb_room_info = []; // 心跳带勋章房间信息
}
/**
* @use init
* @return bool
*/
private static function init(): bool
{
if (getenv('USE_HEARTBEAT') == 'false' || getenv('ENC_SERVER') == '') {
return false;
}
if (is_null(self::$enc_server)) {
self::$enc_server = getenv('ENC_SERVER');
}
return true;
}
/**
* @use 勋章处理
*/
private static function polishMetal()
{
// 灰色勋章
self::fetchGreyMedalList();
if (empty(self::$grey_fans_medals)) {
return;
}
// 小心心
$bag_list = Live::fetchBagListByGift('小心心', 30607);
if (empty($bag_list)) {
return;
}
// 擦亮勋章
foreach ($bag_list as $gift) {
for ($num = 1; $num <= $gift['gift_num']; $num++) {
$grey_fans_medal = array_shift(self::$grey_fans_medals);
// 为空
if (is_null($grey_fans_medal)) break;
// 擦亮
Live::sendGift($grey_fans_medal, $gift, 1);
}
}
}
/**
* @use 心跳处理
*/
private static function heartBeat()
{
if (empty(self::$fans_medals)) {
return;
}
if (empty(self::$hb_room_info)) {
$metal = self::$fans_medals[array_rand(self::$fans_medals)];
$room_info = Live::webGetRoomInfo($metal['roomid']);
}
if (self::$hb_count == 0) {
$e_data = self::eHeartBeat($room_info['data']['room_info']);
if (!$e_data['status']) {
// 错误级别
return;
}
self::$hb_count += 1;
self::$hb_payload = $e_data['payload'];
self::$hb_headers = $e_data['headers'];
return;
}
$x_data = self::xHeartBeat(self::$hb_count);
if (!$x_data['status']) {
// 错误级别
return;
}
self::$hb_count += 1;
}
/**
* @use E心跳
* @param array $room_info
* @param int $index
* @return array|bool[]
*/
private static function eHeartBeat(array $room_info, $index = 0): array
{
$url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/E';
$headers = [
'Content-Type' => 'application/x-www-form-urlencoded',
'Origin' => 'https://live.bilibili.com',
'Referer' => 'https://live.bilibili.com/' . $room_info['room_id'],
];
$user_info = User::parseCookies();
$payload = [
'id' => json_encode([$room_info['parent_area_id'], $room_info['area_id'], $index, $room_info['room_id']], true),
'device' => json_encode([
Generator::hash(), Generator::uuid4()
], true),
'ts' => time() * 1000,
'is_patch' => 0,
'heart_beat' => [],
'ua' => 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
'csrf_token' => $user_info['token'],
'csrf' => $user_info['token'],
'visit_id' => ''
];
$raw = Curl::post('pc', $url, $payload, $headers);
$de_raw = json_decode($raw, true);
// {"code":0,"message":"0","ttl":1,"data":{"timestamp":1595342828,"heartbeat_interval":300,"secret_key":"seacasdgyijfhofiuxoannn","secret_rule":[2,5,1,4],"patch_status":2}}
if ($de_raw['code'] != 0) {
Log::warning("小心心礼物E-{$index}心跳失败");
return ['status' => false];
}
Log::info("小心心礼物E-{$index}心跳成功");
// Log::info($raw);
$payload['ets'] = $de_raw['data']['timestamp'];
$payload['secret_key'] = $de_raw['data']['secret_key'];
$payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval'];
$payload['secret_rule'] = $de_raw['data']['secret_rule'];
return [
'status' => true,
'payload' => $payload,
'headers' => $headers,
];
}
/**
* @use X心跳
* @param int $index
* @return array|bool[]
*/
private static function xHeartBeat(int $index = 1): array
{
$s_data = self::encParamS($index);
$s = $s_data['s'];
$t = $s_data['payload'];
$url = 'https://live-trace.bilibili.com/xlive/data-interface/v1/x25Kn/X';
$user_info = User::parseCookies();
$payload = [
's' => $s,
'id' => $t['id'],
'device' => $t['device'],
'ets' => $t['ets'],
'benchmark' => $t['benchmark'],
'time' => $t['time'],
'ts' => $t['ts'],
'ua' => $t['ua'],
'csrf_token' => $user_info['token'],
'csrf' => $user_info['token'],
'visit_id' => ''
];
// print_r($payload);
$raw = Curl::post('pc', $url, $payload, self::$hb_headers);
$de_raw = json_decode($raw, true);
# {"code":0,"message":"0","ttl":1,"data":{"heartbeat_interval":300,"timestamp":1595346846,"secret_rule":[2,5,1,4],"secret_key":"seacasdgyijfhofiuxoannn"}}
if ($de_raw['code'] != 0) {
Log::warning("小心心礼物X-{$index}心跳失败");
return ['status' => false];
}
self::$hb_payload['ets'] = $de_raw['data']['timestamp'];
self::$hb_payload['secret_key'] = $de_raw['data']['secret_key'];
self::$hb_payload['heartbeat_interval'] = $de_raw['data']['heartbeat_interval'];
Log::info("小心心礼物X-{$index}心跳成功");
return ['status' => true];
}
/**
* @use 加密参数S
* @param int $index
* @return array
*/
private static function encParamS(int $index): array
{
// 转换index
$temp = json_decode(self::$hb_payload['id'], true);
$temp[2] += 1;
self::$hb_payload['id'] = json_encode($temp, true);
// 加密部分
$payload = [
't' => [
'id' => self::$hb_payload['id'],
'device' => self::$hb_payload['device'],
'ets' => self::$hb_payload['ets'],
'benchmark' => self::$hb_payload['secret_key'],
'time' => self::$hb_payload['heartbeat_interval'],
'ts' => time() * 1000,
'ua' => self::$hb_payload['ua']
],
'r' => self::$hb_payload['secret_rule']
];
$headers = [
'Content-Type' => 'application/json',
];
$data = Curl::put('other', self::$enc_server, $payload, $headers);
$de_raw = json_decode($data, true);
Log::info("S参数加密 {$de_raw['s']}");
return [
's' => $de_raw['s'],
'payload' => $payload['t']
];
}
/**
* @use 获取灰色勋章列表(过滤无勋章或已满)
*/
private static function fetchGreyMedalList()
{
$data = Live::fetchMedalList();
$user_info = User::parseCookies();
foreach ($data as $vo) {
// 过滤主站勋章
if (!isset($vo['roomid'])) continue;
// 过滤自己勋章
if ($vo['target_id'] == $user_info['uid']) continue;
// 所有
self::$fans_medals[] = [
'uid' => $vo['target_id'],
'roomid' => $vo['roomid'],
];
// 灰色
if ($vo['medal_color_start'] == 12632256 && $vo['medal_color_end'] == 12632256 && $vo['medal_color_border'] == 12632256) {
self::$grey_fans_medals[] = [
'uid' => $vo['target_id'],
'roomid' => $vo['roomid'],
];
}
}
}
}

View File

@ -24,7 +24,7 @@ class Statistics
private static $success_list = [];
private static $profit_list = [];
// TODO 统计开关 统计时间间隔 统计类型
public static function run()
{
if (self::getLock() > time()) {

View File

@ -116,6 +116,7 @@ class StormRaffle extends BaseRaffle
// {"code":-412,"message":"请求被拦截","ttl":1,"data":null}
if ($de_raw['code'] == -412) {
Log::notice(self::formatInfo($raffle['raffle_id'], $num, '触发哔哩哔哩安全风控策略(-412)'));
break;
}
if ($de_raw['code'] == 429 || $de_raw['code'] == -429) {
Log::notice(self::formatInfo($raffle['raffle_id'], $num, '节奏风暴未实名或异常验证码'));

52
src/tool/Generator.php Normal file
View File

@ -0,0 +1,52 @@
<?php
/**
* Website: https://mudew.com/
* Author: Lkeme
* License: The MIT License
* Email: Useri@live.cn
* Updated: 2020 ~ 2021
* Source: https://github.com/anhao/bv2av/
*/
namespace BiliHelper\Tool;
class Generator
{
/**
* @use 生成uuid4
* @return string
*/
public static function uuid4(): string
{
// 标准的UUID格式为xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12)
// var T = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(t) {
// var e = 16 * Math.random() | 0;
// return ("x" === t ? e : 3 & e | 8).toString(16)
// });
$chars = md5(uniqid(mt_rand(), true));
$chars = substr_replace($chars, "4", 12, 1);
$chars = substr_replace($chars, "a", 16, 1);
$uuid = substr($chars, 0, 8) . '-'
. substr($chars, 8, 4) . '-'
. substr($chars, 12, 4) . '-'
. substr($chars, 16, 4) . '-'
. substr($chars, 20, 12);
return $uuid;
}
/**
* @use 生成hash
* @return string
*/
public static function hash(): string
{
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';
$random = $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)] . $chars[mt_rand(0, 73)];//Random 5 times
$content = uniqid() . $random; // 类似 5443e09c27bf4aB4uT
return md5($content); // sha1
}
}