97 lines
1.8 KiB
PHP
97 lines
1.8 KiB
PHP
<?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));
|
|
}
|
|
} |