年末将至,大部分企业都将举行年会,一是对企业当年的发展成绩做出总结,以及来年的计划、方向、目标等。二是加强员工之间的交流,进一步增强团队之间团结的意识,昨日程序员怼产品、怼测试,化为杯中酒,干了那一杯来年继续怼,哈哈。
三是答谢全体员工一年以来付出的辛勤努力,毕竟给予员工价值的肯定是特么很重要的。
四是公司部门的互动,可以加强团结。编不下去了,哈哈,接入主题,既然是欢天喜地的一天怎么能缺了抽奖这项活动,疑问的是抽奖真的公平吗?或者说有相对公平的抽奖吗?有暗箱操作吗?下面直接上代码来看看是否有相对可公开公平的抽奖方式。
原理
1、参与抽奖的用户 留言+昵称+用户ID+留言时间,最后 SHA256
2、抓取微博头条( https://weibo.com/?category=1760) 第一条新闻内容作为因子,最后 SHA256
3、通过余弦相似度来计算相似度,接近1则表示相似度越高,是不是很easy,且可公开、相对公平
上图
<?php
/**
* 1、通过用户留言+昵称+用户ID+留言时间,通过 SHA256
* 2、抓取微博 https://weibo.com/?category=1760 第一条新闻,通过 SHA256
* 3、通过预先相似度来计算相似度,接近1则表示相似度越高
**/
$count = 10;
for($i = 1; $i <= 500; $i++)
{
$contents[$i] = [
'user_id' => $i,
'nickname' => '用户'.$i,
'content' => '沙发'.$i.'~!希望能中,哈哈!',
'date' => date('Y-m-d H:i:s', rand(1577871914, 1578476714)),
];
}
$info = [];
$weiboNews = getWeiboNews();
if(!$weiboNews) {
echo '初始化失败...';
exit();
}
echo "-------微博数据----------<br />";
echo "weibo-URL\t\t\t".$weiboNews['url']."<br />";
echo "weibo-title\t\t".$weiboNews['title']."<br />";
echo "weibo-date\t\t\t".$weiboNews['date']."<br />";
echo "weibo-sha256\t\t\t".$weiboNews['sha256']."<br />";
echo "-------微博数据----------<br />";
$newSha256 = $weiboNews['sha256'];
$sortField = [];
foreach($contents as $content) {
$hashConetnt = $content['content'].$content['nickname'].$content['user_id'].$content['date'];
$sha256 = hash("sha256", $hashConetnt);
$info[$content['user_id']]['user_id'] = $sha256;
$Similarity = new Similarity($sha256, $newSha256);
$index = $Similarity->run();
$info[$content['user_id']]['index'] = $index;
$info[$content['user_id']]['nickname'] = $content['nickname'];
$sortField[$content['user_id']] = $index;
}
array_multisort($sortField, SORT_DESC, $info);
$result = array_slice($info, 0, $count);
echo "-------中奖用户(中奖用户记得排除掉)----------<br />";
echo '<pre />';
var_dump($result);
/*
* 文本相似度(余弦定理)
* 参考:
* http://www.ruanyifeng.com/blog/2013/03/cosine_similarity.html
* http://my.oschina.net/BreathL/blog/42477
* $obj = new Similarity ($text1, $text2);
* $obj->run();
*/
class Similarity
{
/**
* [排除的词语]
*
* @var array
*/
private $_excludeArr = array('的','了','和','呢','啊','哦','恩','嗯','吧');
/**
* [词语分布数组]
*
* @var array
*/
private $_words = array();
/**
* [分词后的数组一]
*
* @var array
*/
private $_segList1 = array();
/**
* [分词后的数组二]
*
* @var array
*/
private $_segList2 = array();
/**
* [分词两段文字]
*
* @param [type] $text1 [description]
* @param [type] $text2 [description]
*/
public function __construct($text1, $text2)
{
$this->_segList1 = $this->segment($text1);
$this->_segList2 = $this->segment($text2);
}
/**
* [外部调用]
*
* @return [type] [description]
*/
public function run()
{
$this->analyse();
$rate = $this->handle();
return $rate ? $rate : 'errors';
}
/**
* [分析两段文字]
*/
private function analyse()
{
//t1
foreach ($this->_segList1 as $v) {
if (!in_array($v, $this->_excludeArr)) {
if (!array_key_exists($v, $this->_words)) {
$this->_words[$v] = array(1 , 0);
} else {
$this->_words[$v][0] += 1;
}
}
}
//t2
foreach ($this->_segList2 as $v) {
if (!in_array($v, $this->_excludeArr)) {
if (!array_key_exists($v, $this->_words)) {
$this->_words[$v] = array(0 , 1);
} else {
$this->_words[$v][1] += 1;
}
}
}
}
/**
* [处理相似度]
*
* @return [type] [description]
*/
private function handle()
{
$sum = $sumT1 = $sumT2 = 0;
foreach ($this->_words as $word) {
$sum += $word[0] * $word[1];
$sumT1 += pow($word[0], 2);
$sumT2 += pow($word[1], 2);
}
$rate = $sum / (sqrt($sumT1 * $sumT2));
return $rate;
}
/**
* [分词 【http://www.xunsearch.com/scws/docs.php#pscws23】]
*
* @param [type] $text [description]
*
* @return [type] [description]
*
* @description 分词只是一个简单的例子,你可以使用任意的分词服务
*/
private function segment($text)
{
return str_split($text);
}
}
function getWeiboNews()
{
$url = 'https://weibo.com/?category=1760';
$header = [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
'Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7,ja;q=0.6,und;q=0.5,zh-TW;q=0.4',
'Cache-Control: no-cache',
'Cookie: SINAGLOBAL=6893973085108.643.1499326211548; ALF=1593569103; SCF=AvUisbrt3cwZHHksMXeJkytu3BsslfGbD8tXZzet6TWVXYM1EIF2RRrsfz-CmpeRwPaqEuUcHfIJUdlpkr1LgjU.; SUHB=0V5lZNATvIlq6I; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9Whz7iuAvsFA0.i9z-NfASFd; SUB=_2AkMqw5Zef8NxqwJRmPgUxG7jZIV2zAnEieKcn2eFJRMxHRl-yj83qmoDtRB6AUO4sX-fWi0CDEICTjSAQZCGj7NeHYeo; login_sid_t=d7128b9b2c3adb11e0e1373b61c60e0f; cross_origin_proto=SSL; Ugrow-G0=d52660735d1ea4ed313e0beb68c05fc5; YF-V5-G0=2583080cfb7221db1341f7a137b6762e; _s_tentry=-; Apache=5679522709654.829.1576061976880; ULV=1576061976884:75:1:1:5679522709654.829.1576061976880:1574302052875; UOR=www.42xz.com,widget.weibo.com,www.google.com; YF-Page-G0=afcf131cd4181c1cbdb744cd27663d8d|1576121897|1576121897',
'Host: weibo.com',
'Pragma: no-cache',
'Referer: https://s.weibo.com/weibo/%25E5%259C%25B0%25E9%259C%2587%25E5%258F%25B0%25E7%25BD%2591?topnav=1&wvr=6&b=1',
'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
];
$html = http_request($url, [], $header);
$time = time();
if ($html == false) {
return false;
}
$pattern = '#<h3 class=\\\\"list_title_b\\\\"><a href=\\\\"(.*?)\\\\" class=\\\\"S_txt1\\\\" target=\\\\"_blank\\\\">(.*?)<\\\\/a><\\\\/h3>#';
preg_match($pattern, $html, $matches);
if($matches) {
$hashConetnt = $matches[1].$matches[2].$time;
$sha256 = hash("sha256", $hashConetnt);
return [
'sha256' => $sha256,
'url' => $matches[1],
'title' => $matches[2],
'date' => $time
];
} else {
return false;
}
}
/**
* http 请求
* @param $url
* @param array $data
* @param int $second
* @return bool|mixed
*/
function http_request($url, $data = [], $header = [], $second = 5)
{
$curl_handle = curl_init();
curl_setopt($curl_handle, CURLOPT_TIMEOUT, $second);
curl_setopt($curl_handle, CURLOPT_URL, $url);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
if (!empty($header)) {
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header);
}
if (!empty($data)) {
curl_setopt($curl_handle, CURLOPT_POST, 1);
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
$response_json = curl_exec($curl_handle);
//返回结果
if ($response_json) {
curl_close($curl_handle);
return $response_json;
} else {
$error = curl_errno($curl_handle);
curl_close($curl_handle);
return false;
}
}