Skip to content

Commit 3c8519c

Browse files
Add entropy calculator
1 parent 58769b4 commit 3c8519c

3 files changed

Lines changed: 109 additions & 1 deletion

File tree

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
}
3131
},
3232
"require": {
33-
"php": ">=8.0"
33+
"php": ">=8.0",
34+
"ext-mbstring": "*"
3435
},
3536
"scripts": {
3637
"post-install-cmd": "tools/phive install --force-accept-unsigned",

src/Entropy/Shannon.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook Secrets.
5+
*
6+
* (c) Sebastian Feldmann <sf@sebastian-feldmann.info>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace CaptainHook\Secrets\Entropy;
15+
16+
/**
17+
* Secret Detector
18+
*
19+
* @package CaptainHook-Secrets
20+
* @author Sebastian Feldmann <sf@sebastian-feldmann.info>
21+
* @link https://github.com/captainhookphp/secrets
22+
* @since Class available since Release 0.9.1
23+
*/
24+
class Shannon
25+
{
26+
/**
27+
* Return the entropy of a given string
28+
*
29+
* @param string $text
30+
* @return float
31+
*/
32+
public static function entropy(string $text): float
33+
{
34+
if (empty($text)) {
35+
return 0;
36+
}
37+
38+
$charMap = [];
39+
foreach (mb_str_split($text) as $char) {
40+
$charMap[$char] = isset($charMap[$char]) ? $charMap[$char] + 1 : 1;
41+
}
42+
43+
$entropy = 0;
44+
$length = strlen($text);
45+
foreach ($charMap as $char => $amount) {
46+
$p = $amount / $length;
47+
$entropy = $entropy - ($p * log($p, 2));
48+
}
49+
return $entropy;
50+
}
51+
}

tests/Entropy/ShannonTest.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CaptainHook Secrets.
5+
*
6+
* (c) Sebastian Feldmann <sf@sebastian-feldmann.info>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace CaptainHook\Secrets\Entropy;
15+
16+
use CaptainHook\Secrets\Detector;
17+
use CaptainHook\Secrets\Regex\Supplier\Aws;
18+
use PHPUnit\Framework\TestCase;
19+
20+
class ShannonTest extends TestCase
21+
{
22+
public function testEntropyWikiExample(): void
23+
{
24+
$this->assertEquals(1.85, round(Shannon::entropy('1223334444'), 2));
25+
}
26+
27+
public function testEntropyEmptyString(): void
28+
{
29+
$this->assertEquals(0, Shannon::entropy(''));
30+
}
31+
32+
public function testEntropyOneCharacterString(): void
33+
{
34+
$this->assertEquals(0, Shannon::entropy('A'));
35+
}
36+
37+
public function testEntropyMultipleSimilarCharacters(): void
38+
{
39+
$this->assertEquals(0, Shannon::entropy('111111'));
40+
}
41+
42+
public function testEntropyTwoCharacters(): void
43+
{
44+
$this->assertEquals(1.0, Shannon::entropy('111222'));
45+
}
46+
47+
public function testEntropyRegularToken(): void
48+
{
49+
$this->assertTrue(Shannon::entropy('lg45ve1mz1yf21pb30qd') > 4);
50+
}
51+
52+
public function testEntropyLongClassName(): void
53+
{
54+
$this->assertTrue(Shannon::entropy('EntropyDetectionManagerProvider') < 4);
55+
}
56+
}

0 commit comments

Comments
 (0)