39
loading...
This website collects cookies to deliver better user experience
https://www.qrcode.com/
(the official QR code site).Encoding Mode | Value bits |
---|---|
Numeric | 0001 (1) |
Alphanumeric | 0010 (2) |
Byte | 0100 (4) |
Kanji | 1000 (8) |
ECI | 0111 (7) |
RegExp
in JavaScript:const KANJI_RE = /^[\p{Script_Extensions=Han}\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}]*$/u;
const NUMERIC_RE = /^\d*$/;
const ALPHANUMERIC_RE = /^[\dA-Z $%*+\-./:]*$/;
const LATIN1_RE = /^[\x00-\xff]*$/;
const KANJI_RE = /^[\p{Script_Extensions=Han}\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}]*$/u;
function getEncodingMode(string) {
if (NUMERIC_RE.test(string)) {
return 0b0001;
}
if (ALPHANUMERIC_RE.test(string)) {
return 0b0010;
}
if (LATIN1_RE.test(string)) {
return 0b0100;
}
if (KANJI_RE.test(string)) {
return 0b1000;
}
return 0b0111;
}
getEncodingMode('https://www.qrcode.com/') === 4
.Encoding Mode | Version 1-9 | Version 10-26 | Version 27-40 |
---|---|---|---|
Numeric | 10 | 12 | 14 |
Alphanumeric | 9 | 11 | 13 |
Byte | 8 | 16 | 16 |
Kanji | 8 | 10 | 12 |
const LENGTH_BITS = [
[10, 12, 14],
[9, 11, 13],
[8, 16, 16],
[8, 10, 12]
];
function getLengthBits(mode, version) {
// ECI mode folds into byte mode
// Basically it's `Math.floor(Math.log2(mode))` but much faster
// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
const modeIndex = 31 - Math.clz32(mode);
const bitsIndex = version > 26 ? 2 : version > 9 ? 1 : 0;
return LENGTH_BITS[modeIndex][bitsIndex];
}
getLengthBits(4, 2) === 8
we'll need 8 bits, and 23 (the length of our string) in binary is 10111, our first bits are:01000001 0111....
h t t p s : / / w w w . q r c o d e . c o m /
104 116 116 112 115 58 47 47 119 119 119 46 113 114 99 111 100 101 46 99 111 109 47
01000001 01110110 10000111 01000111 01000111
00000111 00110011 10100010 11110010 11110111
01110111 01110111 01110010 11100111 00010111
00100110 00110110 11110110 01000110 01010010
11100110 00110110 11110110 11010010 1111....
11110000
. We still have 3 of the availabe 28 codewords to be filled.65 118 135 71 71 7 51 162 242 247 119 119 114 231 23 38 54 246 70 82 230 54 246 210 240 236 17 236
01000001 01110110 10000111 01000111 01000111
00000111 00110011 10100010 11110010 11110111
01110111 01110111 01110010 11100111 00010111
00100110 00110110 11110110 01000110 01010010
11100110 00110110 11110110 11010010 11110000
11101100 00010001 11101100
getByteData
will need three things:function getByteData(content, lengthBits, dataCodewords) {
const data = new Uint8Array(dataCodewords);
const rightShift = (4 + lengthBits) & 7;
const leftShift = 8 - rightShift;
const andMask = (1 << rightShift) - 1;
const dataIndexStart = lengthBits > 12 ? 2 : 1;
data[0] = 64 /* byte mode */ + (content.length >> (lengthBits - 4));
if (lengthBits > 12) {
data[1] = (content.length >> rightShift) & 255;
}
data[dataIndexStart] = (content.length & andMask) << leftShift;
for (let index = 0; index < content.length; index++) {
const byte = content.charCodeAt(index);
data[index + dataIndexStart] |= byte >> rightShift;
data[index + dataIndexStart + 1] = (byte & andMask) << leftShift;
}
const remaining = dataCodewords - content.length - dataIndexStart - 1;
for (let index = 0; index < remaining; index++) {
const byte = index & 1 ? 17 : 236;
data[index + content.length + 2] = byte;
}
return data;
}
getByteData('https://www.qrcode.com/', 8, 28)
// Uint8Array(26) [65, 166, 135, 71, 71, 7, 51, 162, 242, 247, 119, 119, 114, 231, 23, 38, 54, 246, 70, 82, 230, 54, 246, 210, 240, 236, 17, 236]