forked from nicjes/SonicareGenerator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
88 lines (76 loc) · 3.2 KB
/
index.html
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Philips Sonicare Password Generator</title>
</head>
<body>
<div class="main">
<h1>Philips Sonicare Password Generator</h1>
<form id="form">
<p>
<label for="uid">UID (NFC Tag Serial Number): </label>
<input type="text" id="uid" placeholder="Enter the UID" value="04:EC:FC:A2:94:10:90" />
</p>
<p>
<label for="mfg">MFG (Printed underneath brush head)</label>
<input type="text" id="mfg" placeholder="Enter the MFG" value="221214 12K" />
</p>
<button id="generate">Generate</button>
<p><output id="result" for="uid mfg"></output></p>
</form>
</div>
<script type="text/javascript">
const uidRegex = /^([0-9a-fA-F]{2}:){6}[0-9a-fA-F]{2}$/;
const mfgRegex = /^\d{6} \d{2}[a-zA-Z]$/;
document.getElementById("form").addEventListener("submit", handleGenerate);
function handleGenerate(e) {
e.preventDefault();
let uidInput = document.getElementById("uid").value;
let mfgInput = document.getElementById("mfg").value;
if (uidRegex.test(uidInput) && mfgRegex.test(mfgInput)) {
let uid = uidInput.split(':').map(byteStr => parseInt(byteStr, 16)); // Convert UID to bytes
let mfg = [...mfgInput].map(c => BigInt(c.charCodeAt(0))); // Convert MFG to bytes
let password = generatePassword(uid, mfg);
showResult(password);
} else {
showInvalid();
}
}
function showResult(result) {
document.getElementById("result").innerHTML = `
<p>Generated password: ${result}</p>
<p>NFC Command: 1B:${result},A2:24:00:00:02:00</p>
`;
}
function showInvalid() {
document.getElementById("result").innerHTML = `
<p>Invalid input!</p>
`;
}
// Algorithm by @ATC1441 (https://gist.github.com/atc1441/41af75048e4c22af1f5f0d4c1d94bb56)
function crc16(crc, buffer) {
for (let byte of buffer) {
crc ^= BigInt(byte) << BigInt(8);
for (let i = 0; i < 8; i++) {
if (crc & BigInt(0x8000)) {
crc = (crc << BigInt(1)) ^ BigInt(0x1021);
} else {
crc <<= BigInt(1);
}
crc &= BigInt(0xFFFF);
}
}
return crc;
}
// Algorithm by @ATC1441 (https://gist.github.com/atc1441/41af75048e4c22af1f5f0d4c1d94bb56)
function generatePassword(uid, mfg) {
let crc = crc16(BigInt(0x49A3), uid); // Calculate the UID CRC
crc = crc | crc16(crc, mfg) << BigInt(16); // Calculate the MFG CRC
crc = ((crc >> BigInt(8)) & BigInt(0x00FF00FF)) | ((crc << BigInt(8)) & BigInt(0xFF00FF00)); // Rotate the bytes
let password = crc.toString(16).padStart(8, '0').toUpperCase().replace(/(..)(..)(..)(..)/g, '$1:$2:$3:$4'); // Format the password
return password;
}
</script>
</body>
</html>