fix(openalias): output CRC-32 checksum as uppercase hex string and handle UTF-8 correctly

UTF-8 characters (e.g. '€') will now be handled correctly instead of strictly ASCII.
This commit is contained in:
2026-03-20 20:01:04 -04:00
parent 1621d82c56
commit 901ea165e5

View File

@@ -237,7 +237,6 @@ function simplelogin(verification) {
function openalias(prefix, address, opts) { function openalias(prefix, address, opts) {
// Prefix and address are minimum requirement. // Prefix and address are minimum requirement.
// Everything else is optional. // Everything else is optional.
// Checksum must be last: CRC-32 of the record trimmed of surrounding spaces.
opts = opts || {}; opts = opts || {};
var record = "oa1:" + prefix + " recipient_address=" + address + ";"; var record = "oa1:" + prefix + " recipient_address=" + address + ";";
@@ -247,17 +246,21 @@ function openalias(prefix, address, opts) {
if (opts.amount) { record += " tx_amount=" + opts.amount + ";"; } if (opts.amount) { record += " tx_amount=" + opts.amount + ";"; }
if (opts.paymentId) { record += " tx_payment_id=" + opts.paymentId + ";"; } if (opts.paymentId) { record += " tx_payment_id=" + opts.paymentId + ";"; }
if (opts.signature) { record += " address_signature=" + opts.signature + ";"; } if (opts.signature) { record += " address_signature=" + opts.signature + ";"; }
if (opts.checksum) { record += " checksum=" + crc32(record.trim()) + ";"; } if (opts.checksum) { record += " checksum=" + crc32(record.trim()).toString(16).toUpperCase() + ";"; }
// Checksum must be last: CRC-32 of the record trimmed of surrounding spaces.
return TXT("@", record, CF_COMMENT("OpenAlias > " + prefix.toUpperCase() + (opts.name ? " > " + opts.name : ""))); return TXT("@", record, CF_COMMENT("OpenAlias > " + prefix.toUpperCase() + (opts.name ? " > " + opts.name : "")));
} }
/** /**
* Calculate CRC-32 checksum of a string (returns unsigned 32-bit integer) * Calculate CRC-32 checksum of a string
* Handles UTF-8 strings correctly for use with DNSControl.
* @param {string} str - Input string * @param {string} str - Input string
* @returns {number} CRC-32 value * @returns {number} CRC-32 value
* @see https://github.com/nabijaczleweli/openalias.rs/blob/master/src/crypto_addr.rs
*/ */
function crc32(str) { function crc32(str) {
// 1. Generate the CRC Table
var table = []; var table = [];
for (var i = 0; i < 256; i++) { for (var i = 0; i < 256; i++) {
var c = i; var c = i;
@@ -266,9 +269,16 @@ function crc32(str) {
} }
table[i] = c; table[i] = c;
} }
// 2. Convert string to UTF-8 "binary" string
// This ensures characters like '€' are treated as 3 bytes, not 1.
var utf8Str = unescape(encodeURIComponent(str));
// 3. Calculate CRC
var crc = 0xFFFFFFFF; var crc = 0xFFFFFFFF;
for (var k = 0; k < str.length; k++) { for (var k = 0; k < utf8Str.length; k++) {
crc = table[(crc ^ str.charCodeAt(k)) & 0xFF] ^ (crc >>> 8); crc = table[(crc ^ utf8Str.charCodeAt(k)) & 0xFF] ^ (crc >>> 8);
} }
return (crc ^ 0xFFFFFFFF) >>> 0; return (crc ^ 0xFFFFFFFF) >>> 0;
} }