Support lookup by Random ID

This commit is contained in:
ruan 2024-11-26 18:04:20 +02:00
parent c0e395d566
commit a87c9fa315
5 changed files with 165 additions and 1 deletions

View File

@ -33,7 +33,7 @@ class Check {
$type = $info['type']; $type = $info['type'];
if (!isset($uuid)) { if (!isset($uuid)) {
if (filter_var($name, FILTER_VALIDATE_FLOAT)) { if (filter_var($name, FILTER_VALIDATE_FLOAT) || $page->is_randomid($name)) {
echo "<br>"; echo "<br>";
$page->redirect($page->link("info.php?type=$type&id=$name"), true, false); $page->redirect($page->link("info.php?type=$type&id=$name"), true, false);
return; return;

140
inc/obscureID.php Normal file
View File

@ -0,0 +1,140 @@
<?php
class ObscureID {
const BLOCK_SIZE = 3;
const MINIMUM_OUTPUT_SIZE = (self::BLOCK_SIZE * 2);
const ERROR = -1;
private int $shuffleSecret;
private array $shuffle;
private array $unshuffle;
public function __construct($input) {
$array = explode(":", $input, 2);
$this->shuffle = array();
$this->unshuffle = array();
$this->shuffleSecret = $array[0];
$this->buildShuffleTables($array[1]);
}
public function obscure($input): string {
try {
$secret = (int)$input + $this->shuffleSecret;
$id = (string)$secret;
$id = $this->leftPadInflate($id);
$output = "";
$currentBlock = "";
$firstBlock = true;
for ($i = 0, $len = strlen($id); $i < $len; $i++) {
$currentBlock .= $id[$i];
if (strlen($currentBlock) >= self::BLOCK_SIZE) {
if (!$firstBlock) {
if ($currentBlock === "000") {
$output .= "m";
} else if (strpos($currentBlock, "00") === 0) {
$output .= "v";
} else if ($currentBlock[0] === "0") {
$output .= "z";
}
}
$output .= $this->shuffleIn($currentBlock);
$currentBlock = "";
$firstBlock = false;
}
}
if (!empty($currentBlock)) {
throw new RuntimeException();
}
return strtoupper($output);
} catch (RuntimeException $ex) {
return "error";
}
}
public function reveal($input): int {
try {
$str = strtolower($input);
$output = "";
$currentBlock = "";
for ($i = 0, $pad = 0, $len = strlen($str); $i < $len; $i++) {
switch ($str[$i]) {
case 'm':
$pad = 3;
break;
case 'v':
$pad = 2;
break;
case 'z':
$pad = 1;
break;
default:
$currentBlock .= $str[$i];
break;
}
if (strlen($currentBlock) >= self::BLOCK_SIZE) {
$output .= $this->shuffleOut($currentBlock, $pad);
$currentBlock = "";
$pad = 0;
}
}
if (!empty($currentBlock)) {
throw new RuntimeException();
}
return (int)$output - $this->shuffleSecret;
} catch (RuntimeException $ex) {
return self::ERROR;
}
}
private function leftPadInflate($id): string {
$pad = strlen($id) % self::BLOCK_SIZE;
switch ($pad) {
case 1:
return "00$id";
case 2:
return "0$id";
default:
return $id;
}
}
private function leftPadDeflate($pad, $result): string {
switch ($pad) {
case 0:
return (string)$result;
case 1:
return "0$result";
case 2:
return "00$result";
case 3:
return "000";
default:
throw new RuntimeException();
}
}
private function buildShuffleTables($str) {
for ($i = 0; $i <= 999; $i++) {
$idx = (int)($i * 3);
$hex = substr($str, $idx, 3);
$this->shuffle[$i] = $hex;
$this->unshuffle[$hex] = $i;
}
}
private function shuffleIn($currentBlock): string {
if (isset($this->shuffle[(int)$currentBlock])) {
return $this->shuffle[(int)$currentBlock];
}
throw new RuntimeException("No shuffle input for $currentBlock");
}
private function shuffleOut($currentBlock, $pad): string {
if (isset($this->unshuffle[$currentBlock])) {
return $this->leftPadDeflate($pad, $this->unshuffle[$currentBlock]);
}
throw new RuntimeException("No shuffle output for $currentBlock");
}
}

View File

@ -37,6 +37,8 @@ class Page {
$this->name = $name; $this->name = $name;
$this->obscureID = null;
$this->type = null; $this->type = null;
$this->table = null; $this->table = null;
$this->title = null; $this->title = null;
@ -87,6 +89,10 @@ class Page {
} }
} }
} }
if ($cfg->random_secret !== '') {
require_once './inc/obscureID.php';
$this->obscureID = new ObscureID($cfg->random_secret);
}
$argc = count($this->args); $argc = count($this->args);
$this->page = 1; $this->page = 1;
$page = "1"; $page = "1";
@ -444,6 +450,10 @@ class Page {
} else die; } else die;
} }
function is_randomid($str) {
return $this->obscureID !== null && preg_match("/(?i)^[0-9a-fmvz]+$/", $str);
}
/** /**
* Returns true if a string should be treated as a UUID. * Returns true if a string should be treated as a UUID.
* @param $str * @param $str

View File

@ -27,6 +27,13 @@ class Settings {
// $this->name_link = 'https://example.com'; // $this->name_link = 'https://example.com';
$this->name_link = 'index.php'; $this->name_link = 'index.php';
// If you'd like to use random IDs generated by the plugin from the web interface:
// First, run the following command from your server console:
// > litebans reveal web
// This will dump a large string (1234:abc...) which can be pasted here.
// (Note: this feature requires LiteBans version 2.16.2 or later.)
$this->random_secret = '';
// Show server scope column? // Show server scope column?
$this->show_server_scope = false; $this->show_server_scope = false;

View File

@ -143,6 +143,13 @@ count($args) >= 2 && is_string($args[0]) && is_string($args[1]) or die($page->t(
$type = $args[0]; $type = $args[0];
$id = $args[1]; $id = $args[1];
if ($page->is_randomid($id)) {
$reveal = $page->obscureID->reveal($id);
if ($reveal >= 0) {
$id = $reveal;
}
}
$page->set_info($page->type_info($type)); $page->set_info($page->type_info($type));
($page->type !== null) or die("Unknown page type requested"); ($page->type !== null) or die("Unknown page type requested");