BaseUUID.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace app\common\base\utils;
  3. /**
  4. * 后台控制器基类
  5. * 接口方法权限 必传参数 接口返回 错误抛出 通用参数处理
  6. */
  7. class BaseUUID {
  8. protected $flag = 1; // 1
  9. protected $flagLength = 1; // 1
  10. protected $env = 7; // 3
  11. protected $envLength = 3; // 3
  12. protected $db = 255; // 8
  13. protected $dbLength = 8; // 8
  14. protected $server = 255; // 8
  15. protected $serverLength = 8; // 8
  16. protected $firstLength = 20;
  17. protected $secondLength = 31;
  18. protected $thirdLength = 31;
  19. protected $first36Length = 4;
  20. protected $second36Length = 6;
  21. protected $third36Length = 6;
  22. protected $timeLength = 42; // 0 - 4398046511103
  23. protected $randomLength = 12;
  24. protected $tableLength = 8; // 255
  25. protected $startTime = '1558713600000'; // 2019/5/25 0:0:0(1558713600000) - 2158/10/6 7:35:11(5956760111103)
  26. private function fixLength($str = 0, $length = 0, $slot = '0') {
  27. return substr(str_pad($str, $length, $slot, STR_PAD_LEFT), 0, $length);
  28. }
  29. public function _generateUUID($table = -1) {
  30. $timeStr = $this->generateUUIDTimeBin();
  31. $firstStr = $this->generateUUIDFirstBin();
  32. $secondStr = $this->generateUUIDSecondBin($timeStr);
  33. $thirdStr = $this->generateUUIDThirdBin($timeStr, $table);
  34. $firstStr36 = $this->fixLength(base_convert($firstStr, 2, 36), $this->first36Length);
  35. $secondStr36 = $this->fixLength(base_convert($secondStr, 2, 36), $this->second36Length);
  36. $thirdStr36 = $this->fixLength(base_convert($thirdStr, 2, 36), $this->third36Length);
  37. return $firstStr36.$secondStr36.$thirdStr36;
  38. }
  39. private function generateBin($number = 0, $length = 0) {
  40. return $this->fixLength(decbin($number), $length);
  41. }
  42. private function getMillisecond() {
  43. list($msec, $sec) = explode(' ', microtime());
  44. $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
  45. return substr($msectime,0,13);
  46. }
  47. private function generateUUIDTimeBin() {
  48. $timestamp = $this->getMillisecond();
  49. // return $this->fixLength(decbin($timestamp - $this->startTime), $this->timeLength);
  50. return $this->fixLength(decbin(TimeUtils::getMillisecond() - $this->startTime), $this->timeLength);
  51. }
  52. private function generateUUIDFirstBin() {
  53. $flagStr = $this->generateBin($this->flag, $this->flagLength);
  54. $envStr = $this->generateBin($this->env, $this->envLength);
  55. $dbStr = $this->generateBin($this->db, $this->dbLength);
  56. $serverStr = $this->generateBin($this->server, $this->serverLength);
  57. return $flagStr.$envStr.$dbStr.$serverStr;
  58. }
  59. private function generateUUIDSecondBin($timeStr) {
  60. $startTimeStr = substr($timeStr, 0, $this->secondLength);
  61. return $startTimeStr;
  62. }
  63. private function generateUUIDThirdBin($timeStr, $table = -1) {
  64. $endTimeStr = substr($timeStr, $this->secondLength);
  65. $random = $this->generateRandom(1 << $this->randomLength);
  66. $table = $table === -1 ? $this->generateRandom(1 << $this->tableLength) : $table;
  67. $randomStr = $this->generateBin($random, $this->randomLength);
  68. $tableStr =$this->generateBin($table, $this->tableLength);
  69. return $endTimeStr.$randomStr.$tableStr;
  70. }
  71. private function generateRandom($max) {
  72. return rand(0, $max);
  73. }
  74. public function _pasreUUID($uuid) {
  75. $firstStr36 = substr($uuid, 0, $this->first36Length);
  76. $secondStr36 = substr($uuid, $this->first36Length, $this->second36Length);
  77. $thirdStr36 = substr($uuid, $this->first36Length + $this->second36Length);
  78. $firstStr = $this->pasreBin($firstStr36, $this->firstLength);
  79. $secondStr = $this->pasreBin($secondStr36, $this->secondLength);
  80. $thirdStr = $this->pasreBin($thirdStr36, $this->thirdLength);
  81. [
  82. 'flag' => $flag,
  83. 'env' => $env,
  84. 'db' => $db,
  85. 'server' => $server
  86. ] = $this->pasreExpand($firstStr);
  87. $beforeTime = $secondStr;
  88. [
  89. 'afterTime' => $afterTime,
  90. 'random' => $random,
  91. 'table' => $table,
  92. ] = $this->pasreThirdStr($thirdStr);
  93. $timestamp = $this->startTime + bindec($beforeTime.$afterTime);
  94. return [
  95. 'flag' => $flag,
  96. 'env' => $env,
  97. 'db' => $db,
  98. 'server' => $server,
  99. 'timestamp' => $timestamp,
  100. 'random' => $random,
  101. 'table' => $table,
  102. ];
  103. }
  104. private function pasreBin($str, $length) {
  105. return $this->fixLength(base_convert($str, 36, 2), $length);
  106. }
  107. private function pasreExpand($firstStr) {
  108. $flag = bindec(substr($firstStr, 0 , $this->flagLength));
  109. $env = bindec(substr($firstStr, $this->flagLength , $this->envLength));
  110. $db = bindec(substr($firstStr, $this->flagLength + $this->envLength, $this->dbLength));
  111. $server = bindec(substr($firstStr, $this->flagLength + $this->envLength + $this->dbLength));
  112. return [
  113. 'flag' => $flag,
  114. 'env' => $env,
  115. 'db' => $db,
  116. 'server' => $server
  117. ];
  118. }
  119. private function pasreThirdStr($thirdStr) {
  120. $afterTime = substr($thirdStr, 0, $this->timeLength - $this->secondLength);
  121. $random = bindec(substr($thirdStr, $this->timeLength - $this->secondLength, $this->randomLength));
  122. $table = bindec(substr($thirdStr, $this->timeLength - $this->secondLength + $this->randomLength));
  123. return [
  124. 'afterTime' => $afterTime,
  125. 'random' => $random,
  126. 'table' => $table,
  127. ];
  128. }
  129. public function _pasreTable($uuid) {
  130. $thirdStr36 = substr($uuid, $this->first36Length + $this->second36Length);
  131. $thirdStr = $this->pasreBin($thirdStr36, $this->thirdLength);
  132. [
  133. 'table' => $table,
  134. ] = $this->pasreThirdStr($thirdStr);
  135. return $table;
  136. }
  137. }