123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330 |
- <?php
- namespace App\Base\Library;
- use App\Base\Exceptions\ApiException;
- use App\Basic\Facades\UrlsFacade;
- class Shorty {
-
- private $chars = 'DUuW9Pd0lGE2xZp4aIwOrHYkMA7fCi1Te53VzL6gRKnmtSsFoyNQvcjBqJhX8b';
-
- private $salt = '';
-
- private $padding = 1;
-
- private $hostname = '';
-
- private $connection = null;
-
- private $whitelist = array();
-
- public function __construct($hostname) {
- $this->hostname = $hostname;
- }
-
- public function get_chars() {
- return $this->chars;
- }
-
- public function set_chars($chars) {
- if (!is_string($chars) || empty($chars)) {
- throw new Exception('Invalid input.');
- }
- $this->chars = $chars;
- }
-
- public function get_salt() {
- return $this->salt;
- }
-
- public function set_salt($salt) {
- $this->salt = $salt;
- }
-
- public function get_padding() {
- return $this->padding;
- }
-
- public function set_padding($padding) {
- $this->padding = $padding;
- }
-
- public function encode($n) {
- $k = 0;
- if ($this->padding > 0 && !empty($this->salt)) {
- $k = self::get_seed($n, $this->salt, $this->padding);
- $n = (int)($k.$n);
- }
- return self::num_to_alpha($n, $this->chars);
- }
-
- public function decode($s) {
- $n = self::alpha_to_num($s, $this->chars);
- return (!empty($this->salt)) ? substr($n, $this->padding) : $n;
- }
-
- public static function get_seed($n, $salt, $padding) {
- $hash = md5($n.$salt);
- $dec = hexdec(substr($hash, 0, $padding));
- $num = $dec % pow(10, $padding);
- if ($num == 0) $num = 1;
- $num = str_pad($num, $padding, '0');
- return $num;
- }
-
- public static function num_to_alpha($n, $s) {
- $b = strlen($s);
- $m = $n % $b;
- if ($n - $m == 0) return substr($s, $n, 1);
- $a = '';
- while ($m > 0 || $n > 0) {
- $a = substr($s, $m, 1).$a;
- $n = ($n - $m) / $b;
- $m = $n % $b;
- }
- return $a;
- }
-
- public static function alpha_to_num($a, $s) {
- $b = strlen($s);
- $l = strlen($a);
- for ($n = 0, $i = 0; $i < $l; $i++) {
- $n += strpos($s, substr($a, $i, 1)) * pow($b, $l - $i - 1);
- }
- return $n;
- }
-
- public function fetch($id) {
- $statement = $this->connection->prepare(
- 'SELECT * FROM urls WHERE id = ?'
- );
- $statement->execute(array($id));
- return $statement->fetch(PDO::FETCH_ASSOC);
- }
-
- public function find($url) {
- return UrlsFacade::findOneBy([
- "url" => $url,
- "status" => 0
- ], "id,url");
- }
-
- public function store($url) {
- $info = UrlsFacade::save([
- "url" => $url,
- "status" => 0
- ]);
- return $info->id;
- }
-
- public function update($id, $key) {
- return UrlsFacade::update($id, [
- "key" => $key
- ]);
- }
-
- public function redirect($url) {
- header("Location: $url", true, 301);
- exit();
- }
-
- public function not_found() {
- header('Status: 404 Not Found');
- exit(
- '<h1>404 Not Found</h1>'.
- str_repeat(' ', 512)
- );
- }
-
- public function error($message) {
- exit("<h1>$message</h1>");
- }
-
- public function allow($ip) {
- if (is_array($ip)) {
- $this->whitelist = array_merge($this->whitelist, $ip);
- }
- else {
- array_push($this->whitelist, $ip);
- }
- }
-
- public function run($url)
- {
- $url = urldecode($url);
-
- if (!empty($url)) {
- if (!empty($this->whitelist) && !in_array($_SERVER['REMOTE_ADDR'], $this->whitelist)) {
- throw new ApiException("", "请求地址不在白名单中");
- }
- if (preg_match('/^http[s]?\:\/\/[\w]+/', $url)) {
- $result = $this->find($url);
-
- if (empty($result)) {
- $id = $this->store($url);
- $code = $this->encode($id);
- $url = $this->hostname . '/' . $code;
- $this->update($id, $code);
- } else {
- $url = $this->hostname . '/' . $this->encode($result['id']);
- }
- return $url;
- } else {
- throw new ApiException("", "地址错误");
- }
- } else {
- throw new ApiException("", "地址错误");
- }
- }
- }
|