Skip to content

Instantly share code, notes, and snippets.

@ArrayIterator
Created July 5, 2020 06:15
Show Gist options
  • Select an option

  • Save ArrayIterator/6583acc4c1fe67c4874681636b01de65 to your computer and use it in GitHub Desktop.

Select an option

Save ArrayIterator/6583acc4c1fe67c4874681636b01de65 to your computer and use it in GitHub Desktop.
<?php
/**
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
declare(strict_types=1);
namespace ArrayIterator\DataApi;
use Exception;
/**
* LiveScore API Decryption Class
*
* Class DataApi
* @package ArrayIterator\DataApi
*
* $decoder = new DataApi();
* $json = $decoder->decrypt(); // string
* @license GPLv3 or later
*/
class DataApi
{
/**
* Decrypt plain data from live score api
*
* @param string $body
* @return string returning json if data valid
*/
public function decrypt(string $body): string
{
// <editor-folding>
// data
$data = '';
// "Query-Expiry::: "
$queryFirstColon = ord($body[12]);
$querySecondColon = ord($body[13]);
$queryThirdColon = ord($body[14]);
$querySpace = ord($body[15]);
// data contain body
$startOffsetBody = 0;
$bracketPos = 0;
$tildePos = 0;
$carriageReturn = chr(13);
$lineFeed = chr(10);
$space = chr(32);
$currentOrdinal = null;
$offsetPrev1 = null;
$offsetPrev2 = null;
$modulus = null;
$currentOffset = null;
$magic_point_1 = [];
$magic_point_2 = [];
$magic_point_3 = [];
// YYYY-MM-DD HH:mm:ii
$offsetDate = 0;
$bodyLength = strlen($body);
// </editor-folding>
// <editor-folding>
if (58 === $queryFirstColon && 32 === $querySecondColon) {
$magic_point_1 = [33];
$magic_point_2 = [36];
$magic_point_3 = [37];
$offsetDate = $this->populateDate(substr($body, 14, 19));
$startOffsetBody = 33;
$bracketPos = 40;
$tildePos = 126;
} elseif (58 === $queryFirstColon && 58 === $querySecondColon && 32 === $queryThirdColon) {
$magic_point_1 = [171];
$magic_point_2 = [169];
$magic_point_3 = [187];
$offsetDate = $this->populateDate(substr($body, 15, 19));
$startOffsetBody = 34;
$bracketPos = 40;
$tildePos = 126;
} elseif (58 === $queryFirstColon
&& 58 == $querySecondColon
&& 58 === $queryThirdColon
&& 32 === $querySpace
) {
$magic_point_1 = [33, 36, 34];
$magic_point_2 = [35, 37, 38];
$magic_point_3 = [37, 35, 36];
$offsetDate = $this->populateDate(substr($body, 16, 19));
$startOffsetBody = 35;
$bracketPos = 40;
$tildePos = 126;
}
// </editor-folding>
$sumW = ($tildePos - $bracketPos + 1);
$startingIncrement = $bodyLength - $startOffsetBody;
$increment = $startingIncrement;
while ($increment > 0) {
$currentOffset = $startOffsetBody + $increment - 1;
$currentOrdinal = ord($body[$currentOffset]);
$modulus = ($startingIncrement - $increment + 1) % 10;
if ($currentOrdinal >= $bracketPos && $tildePos >= $currentOrdinal) {
if ($bracketPos > $currentOrdinal - $offsetDate - $modulus) {
$data .= chr($currentOrdinal - $offsetDate - $modulus + $sumW);
} else {
$data .= chr($currentOrdinal - $offsetDate - $modulus);
}
} else {
if ($currentOffset >= 1) {
$offsetPrev1 = ord($body[$currentOffset - 1]);
}
if ($currentOffset >= 2) {
$offsetPrev2 = ord($body[$currentOffset - 2]);
}
if ($this->check($offsetPrev2, $offsetPrev1, $currentOrdinal, $magic_point_1)) {
$increment -= count($magic_point_1) - 1;
$data .= $lineFeed;
} elseif ($this->check($offsetPrev2, $offsetPrev1, $currentOrdinal, $magic_point_2)) {
$increment -= count($magic_point_2) - 1;
$data .= $carriageReturn;
} elseif ($this->check($offsetPrev2, $offsetPrev1, $currentOrdinal, $magic_point_3)) {
$increment -= count($magic_point_3) - 1;
$data .= $space;
} else {
$data .= $body[$currentOffset];
}
}
$increment--;
}
unset($body);
return $data;
}
/**
* @param string $chr
* @return int
* @throws Exception
*/
private function subPopulate(string $chr): int
{
$ordinal = ord($chr);
if ($ordinal >= 48 && 57 >= $ordinal) {
return $ordinal - 48;
}
throw new Exception(
sprintf(
"Char value \"%s\" is not a number character",
$chr
)
);
}
/**
* @param string $dateString
* @return int
*/
protected function populateDate(string $dateString): int
{
$default = 27;
// YYYY-MM-DD HH:mm:ii -> 19
if (!preg_match('
~^[0-9]{4}(-)[0-9]{2}(-)[0-9]{2}(\s)[0-9]{2}(:)[0-9]{2}(:)[0-9]{2}~',
$dateString,
$match,
PREG_OFFSET_CAPTURE
)) {
return $default;
}
array_shift($match);
$range = range(0, 18);
array_map(function ($e) use (&$range) {
unset($range[$e[1]]);
}, $match);
try {
$b = $this->subPopulate($dateString[17]);
$c = $this->subPopulate($dateString[18]);
$e = $this->subPopulate($dateString[11]);
unset($range[17], $range[18], $range[11]);
$f = $b + $c + $e;
foreach ($range as $item) {
$f += $this->subPopulate($dateString[$item]);
}
return (($c >= $b) ? $f + $c - $b : $f + (3 * ($e + 1)));
} catch (Exception $g) {
return $default;
}
}
/**
* @param int $offsetPrev
* @param int $offsetPrev1
* @param int $current
* @param array $bytes
* @return bool
*/
protected function check(int $offsetPrev, int $offsetPrev1, int $current, array $bytes): bool
{
switch (count($bytes)) {
case 1:
return $offsetPrev === $bytes[0];
case 2:
return $offsetPrev === $bytes[0] && $offsetPrev1 === $bytes[1];
case 3:
return $offsetPrev === $bytes[0] && $offsetPrev1 === $bytes[1] && $current === $bytes[2];
default:
return false;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment