/
encdec.php
123 lines (117 loc) · 3.8 KB
/
encdec.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
<?php
$keys = "";
function readKeys(string $path, string &$keys): bool
{
$handle = fopen($path, "rb");
if ($handle === false) {
printf("Failed to open keys file");
return false;
}
$keys = fread($handle, filesize($path));
fclose($handle);
return true;
}
function readDataFile(string $path, string &$buffer, int &$fileSize): bool
{
$handle = fopen($path, "rb");
if ($handle === false) {
printf("Failed to open data file");
return false;
}
$fileSize = filesize($path);
$buffer = fread($handle, $fileSize);
fclose($handle);
return true;
}
function encrypt(string &$decryptedFileRaw, int $length, string $keys): void
{
for ($off = 0; $off < $length;) {
$packetLength = unpack("S", $decryptedFileRaw, $off)[1];
$key = unpack("C", $decryptedFileRaw, $off + 2)[1];
$key = unpack("C", $keys, ($key << 1) % 512)[1];
for ($i = $off + 4; $i < $off + $packetLength; $i++) {
$mappedKey = unpack("C", $keys, (($key % 256) << 1) % 512 + 1)[1];
$currValue = unpack("C", $decryptedFileRaw, $i)[1];
switch ($i & 3) {
case 0:
$currValue = ($currValue + ($mappedKey << 1)) & 255;
break;
case 1:
$currValue = ($currValue - ($mappedKey >> 3)) & 255;
break;
case 2:
$currValue = ($currValue + ($mappedKey << 2)) & 255;
break;
case 3:
$currValue = ($currValue - ($mappedKey >> 5)) & 255;
break;
}
$decryptedFileRaw[$i] = pack("C", $currValue);
$key++;
}
$off += $packetLength;
}
}
function decrypt(string &$encryptedFileRaw, int $length, string $keys): void
{
for ($off = 0; $off < $length;) {
$packetLength = unpack("S", $encryptedFileRaw, $off)[1];
$key = unpack("C", $encryptedFileRaw, $off + 2)[1];
$key = unpack("C", $keys, $key << 1)[1];
for ($i = $off + 4; $i < $off + $packetLength; $i++) {
$mappedKey = unpack("C", $keys, (($key % 256) << 1) % 512 + 1)[1];
$currValue = unpack("C", $encryptedFileRaw, $i)[1];
switch ($i & 3) {
case 0:
$currValue = ($currValue - ($mappedKey << 1)) & 255;
break;
case 1:
$currValue = ($currValue + ($mappedKey >> 3)) & 255;
break;
case 2:
$currValue = ($currValue - ($mappedKey << 2)) & 255;
break;
case 3:
$currValue = ($currValue + ($mappedKey >> 5)) & 255;
break;
}
$encryptedFileRaw[$i] = pack("C", $currValue);
$key++;
}
$off += $packetLength;
}
}
if ($argc < 5) {
exit(-1);
}
if (readKeys($argv[1], $keys) === false) {
exit(-2);
}
$encryptedFileRaw = "";
$encryptedFileRawSize = 0;
if (readDataFile($argv[3], $encryptedFileRaw, $encryptedFileRawSize) === false) {
exit(-3);
}
$decryptedFileRaw = "";
$decryptedFileRawSize = 0;
if (readDataFile($argv[4], $decryptedFileRaw, $decryptedFileRawSize) === false) {
exit(-4);
}
$op = $argv[2];
if ($op === "enc") {
encrypt($decryptedFileRaw, $decryptedFileRawSize, $keys);
$out = fopen("./encoded.bin", "wb");
fwrite($out, $decryptedFileRaw);
fclose($out);
}
if ($op === "dec") {
decrypt($encryptedFileRaw, $encryptedFileRawSize, $keys);
$out = fopen("./decoded.bin", "wb");
fwrite($out, $encryptedFileRaw);
fclose($out);
}
$diff = 0;
for ($i = 0; $i < $encryptedFileRawSize; $i++) {
$diff += ($encryptedFileRaw[$i] !== $decryptedFileRaw[$i]);
}
printf("%d differences", $diff);