<script>
const getDeviceInformation = () => {
return {
userAgent: navigator.userAgent,
platform: navigator.platform,
screenWidth: window.screen.width,
screenHeight: window.screen.height,
};
};
function sha256(hex) {
return crypto.subtle
.digest("SHA-256", new TextEncoder().encode(hex))
.then((buffer) => {
return Array.prototype.map
.call(new Uint8Array(buffer), (x) =>
("00" + x.toString(16)).slice(-2)
)
.join("");
});
}
const bin2hex = (base64) => {
var raw = base64;
console.log(raw);
var hex = "";
for (var i = 0; i < raw.length; i++) {
var charCode = raw.charCodeAt(i).toString(16);
hex += charCode.length === 1 ? "0" + charCode : charCode;
}
return hex;
};
const getFingerprintId = async (content, options = {}) => {
if (!content) {
console.error("content is empty");
return null;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// 如果不存在,则返回空值,说明不支持Canvas指纹
if (!ctx) return null;
const txt = content || "geekbang";
ctx.textBaseline =
options && options.textBaseline ? options.textBaseline : "top";
ctx.font = options && options.font ? options.font : "14px 'Arial'";
ctx.fillStyle =
options && options.reactStyle ? options.reactStyle : "#f60";
// 先画一个60x20矩形内容
ctx.fillRect(125, 1, 60, 20);
ctx.fillStyle =
options && options.contentStyle ? options.contentStyle : "#069";
// 把字填充到矩形内
ctx.fillText(txt, 2, 15);
const b64 = canvas.toDataURL().replace("data:image/png;base64,", "");
const bin = atob(b64);
const crc = bin2hex(bin.slice(-16, -12));
const hash = await sha256(crc + JSON.stringify(getDeviceInformation()));
document.write("<p>SHA-256 哈希值为: " + hash + "</p>");
return hash;
};
window.onload = () => getFingerprintId("abc");
</script>