Some BINKP optimisation, implemented crypt, implemented receiving compressed transfers
This commit is contained in:
97
app/Classes/Crypt.php
Normal file
97
app/Classes/Crypt.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes;
|
||||
|
||||
use App\Interfaces\CRC as CRCInterface;
|
||||
|
||||
class Crypt implements CRCInterface
|
||||
{
|
||||
private array $keys= [
|
||||
305419896,
|
||||
591751049,
|
||||
878082192,
|
||||
];
|
||||
|
||||
public function __construct(string $password)
|
||||
{
|
||||
$this->extend_key($password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update crc.
|
||||
*/
|
||||
private function crc32_cr(int $oldCrc, int $charAt): int
|
||||
{
|
||||
return (($oldCrc >> 8) & 0xFFFFFF) ^ self::crc32_tab[($oldCrc ^ $charAt) & 0xFF];
|
||||
}
|
||||
|
||||
public function decrypt(string $content): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
foreach (unpack('C*', $content) as $byte) {
|
||||
$byte = ($byte ^ $this->decrypt_byte()) & 0xFF;
|
||||
$this->update_keys($byte);
|
||||
$result .= chr($byte);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt byte.
|
||||
*/
|
||||
private function decrypt_byte(): int
|
||||
{
|
||||
$temp = $this->keys[2] | 2;
|
||||
|
||||
return (($temp * ($temp ^ 1)) >> 8) & 0xFFFFFF;
|
||||
}
|
||||
|
||||
public function encrypt(string $content): string
|
||||
{
|
||||
$result = '';
|
||||
|
||||
foreach (unpack('C*', $content) as $val)
|
||||
$result .= pack('c', $this->encrypt_byte($val));
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private function encrypt_byte(int $byte): int
|
||||
{
|
||||
$result = $byte ^ $this->decrypt_byte() & 0xFF;
|
||||
$this->update_keys($byte);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function extend_key(string $password): void
|
||||
{
|
||||
foreach (unpack('C*', $password) as $byte)
|
||||
$this->update_keys($byte);
|
||||
}
|
||||
|
||||
public static function toSignedInt32(int $int): int
|
||||
{
|
||||
if (\PHP_INT_SIZE === 8) {
|
||||
$int &= 0xFFFFFFFF;
|
||||
|
||||
if ($int & 0x80000000)
|
||||
return $int - 0x100000000;
|
||||
}
|
||||
|
||||
return $int;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update keys.
|
||||
*/
|
||||
private function update_keys(int $byte): void
|
||||
{
|
||||
$this->keys[0] = $this->crc32_cr($this->keys[0],$byte);
|
||||
$this->keys[1] += ($this->keys[0] & 0xFF);
|
||||
$this->keys[1] = $this->toSignedInt32($this->keys[1]*134775813+1);
|
||||
$this->keys[2] = $this->toSignedInt32($this->crc32_cr($this->keys[2],($this->keys[1] >> 24) & 0xFF));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user