Skip to content

Commit

Permalink
add doc ShiftedNumber
Browse files Browse the repository at this point in the history
  • Loading branch information
nepster-web committed Oct 20, 2021
1 parent e0645a5 commit 0cadd9a
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 16 deletions.
11 changes: 8 additions & 3 deletions docs/guide/ShiftedNumber.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
Shifted number
==============

------------------
Shifts the specified number using a hash.

**Example:**

----

```php
$number = ((new ShiftedNumber())
->setMin(0)
->setMax(100))
(42, 'my_hash');
```

<br>

Expand Down
44 changes: 31 additions & 13 deletions src/ShiftedNumber.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@

namespace Gambling\Tech;

use ErrorException;
use Exception;

/**
* Base value shifting by hash
*/
class ShiftedNumber
{
private float $min = 0;
private int $min = 0;

private float $max = 100;
private int $max = 100;

/**
* @param float $number
Expand All @@ -22,25 +25,25 @@ public function __invoke(float $number, string $hash): int
{
$shiftValue = $this->getShiftValue($hash);

return $this->shift($number, $shiftValue);
return (int)$this->shift($number, $shiftValue);
}

/**
* @param float $min
* @param int $min
* @return $this
*/
public function setMin(float $min): self
public function setMin(int $min): self
{
$this->min = $min;

return $this;
}

/**
* @param float $max
* @param int $max
* @return $this
*/
public function setMax(float $max): self
public function setMax(int $max): self
{
$this->max = $max;

Expand All @@ -50,25 +53,40 @@ public function setMax(float $max): self
/**
* @param float $number
* @param int $shift
* @return int
* @return float
*/
protected function shift(float $number, int $shift): int
protected function shift(float $number, int $shift): float
{
if ($shift > $this->max) {
$shift %= ($this->max - $this->min + 1);
}

return $number + $shift <= $this->max ?
$shift = $shift === 0 ? (int)(7 / 100 * $this->max) : $shift;

$result = $number + $shift <= $this->max ?
$number + $shift :
$this->min + ($number + $shift - $this->max) - 1;

if ($result < $this->min || $result > $this->max) {
$float = round(($this->min / ($this->max + 1)) + M_PI, 5);
$percent = (int)mb_substr((string)$float, -2, 2);
$result = ($this->min === 0 ? $this->max / 2 : $this->min) + ($percent / 100 * $this->min);
$result = $result > $this->max ? $this->max : $result;
}

return $result;
}

/**
* @param string $clientHash
* @param string $hash
* @return int
*/
protected function getShiftValue(string $clientHash): int
protected function getShiftValue(string $hash): int
{
return (int)hexdec(substr($clientHash, -5));
if (preg_match("/^([a-f0-9])$/", $hash) === 0) {
$hash = sha1($hash);
}

return (int)hexdec(mb_substr($hash, -5));
}
}
66 changes: 66 additions & 0 deletions tests/ShiftedNumberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Gambling\TechTest;

use Gambling\Tech\ShiftedNumber;
use PHPUnit\Framework\TestCase;

class ShiftedNumberTest extends TestCase
{
public function testShiftedNumber(): void
{
$hash = sha1('hash');
$number = (new ShiftedNumber())(7, $hash);

self::assertNotEquals(7, $number);
}

public function testReproduceShiftedNumber(): void
{
$hash = sha1('hash');
$number = (new ShiftedNumber())(7, $hash);

self::assertEquals(1, $number);
}

public function testMinLimit(): void
{
$min = 100;
$pinpoint = false;

for ($i = 0; $i < 100; ++$i) {
$number = ((new ShiftedNumber())
->setMin($min)->setMax(1000))($i, sha1(uniqid('', true)));
if ($min > $number) { echo $number . ' ';
$pinpoint = true;
}
}

self::assertFalse($pinpoint);
}

public function testMaxLimit(): void
{
$max = 1000;
$pinpoint = false;

for ($i = 0; $i < 100; ++$i) {
$number = ((new ShiftedNumber())
->setMin(100)->setMax($max))($i, sha1(uniqid('', true)));
if ($number > $max) {
$pinpoint = true;
}
}

self::assertFalse($pinpoint);
}

public function testShiftedNumberByRandomString(): void
{
$number = (new ShiftedNumber())(7, 'my_random_string');

self::assertNotEquals(7, $number);
}
}

0 comments on commit 0cadd9a

Please sign in to comment.