Skip to content

Instantly share code, notes, and snippets.

@dangdungcntt
Created October 17, 2019 06:09
Show Gist options
  • Save dangdungcntt/63c7a3560af5cfc1b9bd076f7a65d508 to your computer and use it in GitHub Desktop.
Save dangdungcntt/63c7a3560af5cfc1b9bd076f7a65d508 to your computer and use it in GitHub Desktop.
Simple data protect in php. Javascript version here: https://github.com/dangdungcntt/data-protect
<?php
class DataProtect
{
protected static function substrAndToInt($string, $index = 0, $length = 3)
{
return hexdec(self::unmix(substr($string, $index, $length)));
}
protected static function pad($string, $length = 6, $char = '0')
{
return (strlen($string) < $length ? str_repeat($char, $length - strlen($string)) . $string : $string);
}
protected static function mix($string)
{
$firstSeg = floor(strlen($string) / 2);
return self::pad(rand(1, 99) . '', 2)
. substr($string, 0, $firstSeg)
. self::pad(rand(1, 99) . '', 2)
. substr($string, $firstSeg, strlen($string) - $firstSeg)
. self::pad(rand(1, 99) . '', 2);
}
protected static function unmix($string)
{
$originalLength = strlen($string) - 6;
$firstSeg = floor($originalLength / 2);
return substr($string, 2, $firstSeg) . substr($string, $firstSeg + 4, $originalLength - $firstSeg);
}
/**
* @param $input
* @param $secret
* @param int $seg
* @return string
* @throws \Exception
*/
public static function encrypt($input, $secret, $seg = 3)
{
if (!in_array($seg, range(2, 15))) {
throw new \Exception('Invalid seg. seg must between 2-15');
}
if (!$input) {
throw new \Exception('Invalid input. Input must not empty');
}
if (!$secret) {
throw new \Exception('Invalid secret. Secret must not empty');
}
$decSeg = hexdec(str_repeat('f', $seg));
$time = round($decSeg * rand(0, 1000) / 1000);
$key = 10;
foreach (str_split($secret) as $cur) {
$key = ($key * 10 % $decSeg) + (ord($cur) % $decSeg);
$key %= $decSeg;
}
$base = $key ^ $time;
$time16 = dechex($time);
$output = self::mix(self::pad($time16, $seg));
foreach (str_split(trim($input)) as $c) {
$output .= '' . self::mix(self::pad(dechex(ord($c) ^ $base), $seg));
}
return $output;
}
/**
* @param $encrypted
* @param $secret
* @param int $seg
* @return string
* @throws \Exception
*/
public static function decrypt($encrypted, $secret, $seg = 3)
{
if (!in_array($seg, range(2, 15))) {
throw new \Exception('Invalid seg. seg must between 2-15');
}
if (!$encrypted) {
throw new \Exception('Invalid encrypted. Encrypted must not empty');
}
if (!$secret) {
throw new \Exception('Invalid secret. Secret must not empty');
}
$decSeg = hexdec(str_repeat('f', $seg));
$seg += 6;
$key = 10;
foreach (str_split($secret) as $cur) {
$key = ($key * 10 % $decSeg) + (ord($cur) % $decSeg);
$key %= $decSeg;
}
$time = self::substrAndToInt($encrypted, 0, $seg);
$base = $key ^ $time;
$result = '';
$encryptedLength = strlen($encrypted);
for ($i = $seg; $i < $encryptedLength; $i += $seg) {
$result .= chr(self::substrAndToInt($encrypted, $i, $seg) ^ $base);
}
return $result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment