ShortUrl.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. namespace app\index\controller;
  3. use app\index\model\ShortUrlModel;
  4. use app\index\service\HelperService;
  5. use think\Controller;
  6. use think\Validate;
  7. class ShortUrl extends CmsController
  8. {
  9. public function index(){
  10. $params = $this->request->param();
  11. $rule = [
  12. 'old_url'=>'require'
  13. ];
  14. $validate = new Validate($rule);
  15. if(!$validate->check($params)){
  16. HelperService::returnJson([
  17. 'code'=>400,
  18. 'msg'=>$validate->getError(),
  19. 'data'=>""
  20. ]);
  21. }
  22. $num = 0;
  23. $flag = 'NEW';
  24. while(true){
  25. $shortUrlModel = new ShortUrlModel();
  26. $res = $shortUrlModel->where(['old_url'=>"{$params['old_url']}"])->find();
  27. if($res){
  28. $url_str = $res['url_str'];
  29. $flag = 'OLD';
  30. break;
  31. }
  32. $random = rand(0,9999);
  33. $random = str_pad($random,4,'0',STR_PAD_LEFT);
  34. $url_str = $this->createShortUrl("{$params['old_url']}",$random);
  35. //首先看库里有没有没有插入
  36. $res = $shortUrlModel->where(['url_str'=>"{$url_str}"])->find();
  37. if(empty($res)){
  38. break;
  39. }
  40. $num++;
  41. }
  42. if('NEW' == $flag){
  43. $shortUrlModel = new ShortUrlModel();
  44. $shortUrlModel->insert([
  45. 'old_url'=>"{$params['old_url']}",
  46. 'url_str'=>"{$url_str}",
  47. 'num'=>$num,
  48. ]);
  49. }
  50. HelperService::returnJson([
  51. 'code'=>200,
  52. 'msg'=>"http://{$_SERVER['HTTP_HOST']}?to={$url_str}",
  53. 'data'=>$flag
  54. ]);
  55. }
  56. private function createShortUrl($or_url,$salt){
  57. $md5_url = md5($or_url);
  58. //$salt = '0826';//这里不高于aaaa就不会出现61以上的数字,所以来说,后面的特别符号是不会出现的!
  59. $md5_url = $this->addSalt($md5_url,$salt);
  60. $short_url = '';
  61. for($i=0;$i<6;$i++){
  62. $current_str = substr($md5_url,$i*6,6);
  63. //处理当前串的值
  64. $short_url .= $this->ZChar($current_str);
  65. }
  66. return $short_url;
  67. }
  68. /**
  69. * 处理字符串
  70. * @param $str
  71. * @return int
  72. */
  73. private function dealStr($str){
  74. if(strlen($str) != 6){
  75. die("dealStr:{$str}error");
  76. }
  77. $count = '';
  78. for($i=0;$i<6;$i++){
  79. //加权,避免不同序列的和一致
  80. $number = hexdec($str[$i])*($i+1)%12;
  81. $count += $number;
  82. }
  83. return $count % 66;
  84. }
  85. /**
  86. * 字码表
  87. * @param $char_point
  88. * @return mixed
  89. */
  90. private function char($char_point){
  91. $char_array = ["0","1","2","3","4","5",
  92. "6","7","8","9","a","b","c","d",
  93. "e","f","g","h","i","j","k","l",
  94. "m","n","o","p","q","r","s","t",
  95. "u","v","w","x","y","z","A","B",
  96. "C","D","E","F","G","H","I","J",
  97. "K","L","M","N","O","P","Q","R",
  98. "S","T","U","V","W","X","Y","Z",
  99. "$","@",'+',"="];
  100. $char_point = intval($char_point);
  101. if($char_point < 0 || $char_point > 65){
  102. die('char:'.$char_point.' error');
  103. }
  104. return $char_array[$char_point];
  105. }
  106. /**
  107. * 添加盐
  108. * @param $md5_url
  109. * @param $salt
  110. * @return string
  111. */
  112. private function addSalt($md5_url,$salt){
  113. if(strlen($md5_url) != 32){
  114. die('addSalt:{$md5_url} error');
  115. }
  116. $len = strlen($salt);
  117. for($i=0;$i<$len;$i++){
  118. $position = hexdec($md5_url[$i]);
  119. $weight = ceil($position/8);
  120. $position = $position * $weight;
  121. $pre = substr($md5_url,0,$position);
  122. $next = substr($md5_url,$position);
  123. $md5_url = $pre.$salt[$i].$next;
  124. }
  125. return $md5_url;
  126. }
  127. /**
  128. * 加密字节
  129. * @param $current_str
  130. * @return mixed
  131. */
  132. private function ZChar($current_str){
  133. $Vchar = $this->dealStr($current_str);
  134. return $this->char($Vchar);
  135. }
  136. }