i’m trying to make a qr code generator while reading these:
- ISO IEC 18004 2015 Standard.pdf
- https:www.thonky.com/qr-code-tutorial
*
modes
| mode | indicator | note |
|---|---|---|
| eci | 0111 | extended channel interpretation (e.g. utf-8) |
| numeric | 0001 | alphanumeric table |
| alphanumeric | 0010 | |
| byte | 0100 | |
| kanji | 1000 | shift JIS |
| structured append | 0011 | encode data into multiple qr codes (max 16) |
| fnc1 | 0101(1st) /1001(2nd) | turn qr code into gs1 barcode |
mixing modes
multiple modes can be used in single qr code.
this can be done because we specify the length of each data segment.
example:
ECI(utf-8) - BYTE(data1) - ALPHANUMERIC(data2) - KANJI(data3)
extended channel interpretation (ECI) mode
we can encode data into various encodings like utf-8, ISO/IEC 8859-1(latin-1), ISO/IEC 8859-2(latin-2), and even raw bytes.
i had hard time understanding the ECI mode. the ECI mode only contains encoding format data like utf-8 and this instructs how to decode following data (usually byte mode data).
example 1:
ECI(utf-8) - BYTE(data1)
we treat data1 as utf-8 string.
example 2:
ECI(utf-8) - BYTE(data1) - NUMERIC(data2) - ECI(shift_jis) - BYTE(data3)
we treat
data1as utf-8 string.data2as numeric data.data3as shift_jis data.
kanji mode
kanjis can be encoded with utf-8 but, kanji mode is more efficient.
about utf-8
there are several ways to use utf-8 in qrcode
- just use utf-8 bytes some qrcode reader can just detect if utf-8 is used but others doesn’t.
- ECI mode we can define to use utf-8 encoding using ECI mode. but similarly, some qrcode reader doesn’t support ECI mode.
- byte order mark (BOM)
we can use byte order mark (BOM)
0xEF 0xBB 0xBFat the front of the bytes.
error correction
qrcode uses Reed–Solomon error correction
error correction levels:
| level | capability |
|---|---|
| L(low) | 7% |
| M(medium) | 15% |
| Q(quartile) | 25% |
| H(high) | 30% |
versions
the different sizes of qr codes are called versions.
version N is (17+4N)x(17+4N) pixels (1 <= N <= 40) so, version 1 is 21x21, version 2 is 25x25, … , version 39 is 173x173, version 40 is 177x177.
since each version has a maximum capacity, we should choose version that fits out data.
we can determine version to use for data with character capacities table
character counting
for each version and mode, data character count reserves a specific bits.
| ver | num | alphanum | byte | kanji |
|---|---|---|---|---|
| 1-9 | 10 bits | 9 bits | 8 bits | 8 bits |
| 10-26 | 12 bits | 11 bits | 16 bits | 10 bits |
| 27-40 | 14 bits | 14 bits | 16 bits | 12 bits |
data encoding
numeric mode [0001]
split digits into group of three digits (ltr). last group can be one or two digits long.
for non last group with number N:
- convert to 10 bits binary
for last group with number N:
- 0 <= N <= 9 : 4 bits binary
- 10 <= N <= 99 : 7 bits binary
- 100 <= N <= 999 : 10 bits binary
and yes, article that i read[↗] was wrong. look at [7.4.3 Numeric mode] in the ISO/IEC 18004:2015 QR code standard specification.
example
=== example start ===
let's assume err corr level as L(low).
[42805902]
→ numeric mode <0001>
→ 8 chars → ver 1 → <00 00001000>
[42805902]
↓
[428] [059] [02]
↓
[428] [59] [2]
↓
<01 10101100> <00 00111011> <0010>
↓
<01101011 00000011 10110010>
↓
final bits:
<0001 0000001000 01101011 00000011
10110010>
=== example end ===
alphanumeric mode [0010]
split characters into group of two characters (ltr). last group can be a single character.
for each pair, treat two character as a base 45 number and convert to 11 bits binary (left pad with zeros).
if the pair is [RA], R and A each converts to 27 and 10 so in base 45, it’s (27 × 45) + 10 = 1225 = 100 1100 1001(2)
if last group is a single character, convert it to 6 bits binary.
example
=== example start ===
let's assume err corr level as L(low).
[RAWPLUG2026 10 15]
→ alphanumeric mode <0010>
→ 18 chars → ver 1 → <00 00010010>
[RAWPLUG2026 10 15]
↓
[RA] [WP] [LU] [G2] [02] [6 ] [10] [ 1] [5]
↓
[WP] → (32 * 45) + 25 = 1465 = <101 10111001>
[RA] → (27 * 45) + 10 = 1225 = <100 11001001>
[LU] → (21 * 45) + 30 = 975 = <011 11001111>
[G2] → (16 * 45) + 2 = 722 = <010 11010010>
[02] → ( 0 * 45) + 2 = 2 = <000 00000010>
[6 ] → ( 6 * 45) + 36 = 0306 = <001 00110010>
[10] → ( 1 * 45) + 0 = 45 = <000 00101101>
[ 1] → (36 * 45) + 1 = 1621 = <110 01010101>
[5] → 5 = <000101>
↓
<10110111 00110011 00100101 11100111
10101101 00100000 00000100 01001100
10000001 01101110 01010101 000101>
↓
final bits:
<0010 0000010010 10110111 00110011
00100101 11100111 10101101 00100000
00000100 01001100 10000001 01101110
01010101 000101>
=== example end ===
kanji mode [1000]
…
i don’t know whether should i learn about this mode, honestly.
byte mode [0100]
when it comes to bytes, there’s nothing to encode. bytes are just raw binary data.
example
=== example start ===
let's assume err corr level as L(low).
[6D AC D3 B4 25 12]
→ byte mode <0100>
→ 6 chars(bytes) → ver 1 → <00 00000110>
[6D AC D3 B4 25 12]
↓
<01101101 10101100 11010011 10110100 00100101 00010010>
↓
final bits:
<0100 0000000110 01101101 10101100
11010011 10110100 00100101 00010010>
=== example end ===
ECI mode [0111]
byte mode alone doesn’t contains data about encoding by default (some qrcode readers do detect utf-8). using ECI mode, we can define encoding for byte mode.
ECI Designator:
| assignment value | no. | bits |
|---|---|---|
| 000000-000127 | 1 | 0bbbbbbb(2) (8-bit) |
| 000128-016383 | 2 | 10bbbbbb bbbbbbbb(2) (16-bit) |
| 016384-999999 | 3 | 110bbbbb bbbbbbbb bbbbbbbb(2) (24-bit) |
| (where b…b is value bits) |
list of supported ECI encodings[↗]
example
=== example start ===
let's assume err corr level as L(low).
[bong]
→ eci mode <0111>
→ utf-8 format \000026 → <00011010>
→ byte mode <0100>
→ 4 chars(bytes) → ver 1 → <00 00000100>
[bong]
↓
[62 6F 6E 67]
↓
<01100010 01101111 01101110 01100111>
final bits:
<0111 00011010 0100 00 00000100
01100010 01101111 01101110 01100111>
=== example end ===
appendix
a. alphanumeric table
uppercase only for alphabets.
alphanumeric table
| char | index | note |
|---|---|---|
| 0 | 0 | |
| 1 | 1 | |
| 2 | 2 | |
| 3 | 3 | |
| 4 | 4 | |
| 5 | 5 | |
| 6 | 6 | |
| 7 | 7 | |
| 8 | 8 | |
| 9 | 9 | |
| A | 10 | |
| B | 11 | |
| C | 12 | |
| D | 13 | |
| E | 14 | |
| F | 15 | |
| G | 16 | |
| H | 17 | |
| I | 18 | |
| J | 19 | |
| K | 20 | |
| L | 21 | |
| M | 22 | |
| N | 23 | |
| O | 24 | |
| P | 25 | |
| Q | 26 | |
| R | 27 | |
| S | 28 | |
| T | 29 | |
| U | 30 | |
| V | 31 | |
| W | 32 | |
| X | 33 | |
| Y | 34 | |
| Z | 35 | |
| 36 | (space) | |
| $ | 37 | |
| % | 38 | |
| * | 39 | |
| + | 40 | |
| - | 41 | |
| . | 42 | |
| / | 43 | |
| : | 44 |
b. character capacities
character capacities
| ver | err corr | num | alphanum | byte | kanji | . | ver | err corr | num | alphanum | byte | kanji |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | L | 41 | 25 | 17 | 10 | . | 21 | L | 2232 | 1352 | 929 | 572 |
| M | 34 | 20 | 14 | 8 | . | M | 1708 | 1035 | 711 | 438 | ||
| Q | 27 | 16 | 11 | 7 | . | Q | 1224 | 742 | 509 | 314 | ||
| H | 17 | 10 | 7 | 4 | . | H | 969 | 587 | 403 | 248 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 2 | L | 77 | 47 | 32 | 20 | . | 22 | L | 2409 | 1460 | 1003 | 618 |
| M | 63 | 38 | 26 | 16 | . | M | 1872 | 1134 | 779 | 480 | ||
| Q | 48 | 29 | 20 | 12 | . | Q | 1358 | 823 | 565 | 348 | ||
| H | 34 | 20 | 14 | 8 | . | H | 1056 | 640 | 439 | 270 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 3 | L | 127 | 77 | 53 | 32 | . | 23 | L | 2620 | 1588 | 1091 | 672 |
| M | 101 | 61 | 42 | 26 | . | M | 2059 | 1248 | 857 | 528 | ||
| Q | 77 | 47 | 32 | 20 | . | Q | 1468 | 890 | 611 | 376 | ||
| H | 58 | 35 | 24 | 15 | . | H | 1108 | 672 | 461 | 284 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 4 | L | 187 | 114 | 78 | 48 | . | 24 | L | 2812 | 1704 | 1171 | 721 |
| M | 149 | 90 | 62 | 38 | . | M | 2188 | 1326 | 911 | 561 | ||
| Q | 111 | 67 | 46 | 28 | . | Q | 1588 | 963 | 661 | 407 | ||
| H | 82 | 50 | 34 | 21 | . | H | 1228 | 744 | 511 | 315 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 5 | L | 255 | 154 | 106 | 65 | . | 25 | L | 3057 | 1853 | 1273 | 784 |
| M | 202 | 122 | 84 | 52 | . | M | 2395 | 1451 | 997 | 614 | ||
| Q | 144 | 87 | 60 | 37 | . | Q | 1718 | 1041 | 715 | 440 | ||
| H | 106 | 64 | 44 | 27 | . | H | 1286 | 779 | 535 | 330 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 6 | L | 322 | 195 | 134 | 82 | . | 26 | L | 3283 | 1990 | 1367 | 842 |
| M | 255 | 154 | 106 | 65 | . | M | 2544 | 1542 | 1059 | 652 | ||
| Q | 178 | 108 | 74 | 45 | . | Q | 1804 | 1094 | 751 | 462 | ||
| H | 139 | 84 | 58 | 36 | . | H | 1425 | 864 | 593 | 365 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 7 | L | 370 | 224 | 154 | 95 | . | 27 | L | 3517 | 2132 | 1465 | 902 |
| M | 293 | 178 | 122 | 75 | . | M | 2701 | 1637 | 1125 | 692 | ||
| Q | 207 | 125 | 86 | 53 | . | Q | 1933 | 1172 | 805 | 496 | ||
| H | 154 | 93 | 64 | 39 | . | H | 1501 | 910 | 625 | 385 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 8 | L | 461 | 279 | 192 | 118 | . | 28 | L | 3669 | 2223 | 1528 | 940 |
| M | 365 | 221 | 152 | 93 | . | M | 2857 | 1732 | 1190 | 732 | ||
| Q | 259 | 157 | 108 | 66 | . | Q | 2085 | 1263 | 868 | 534 | ||
| H | 202 | 122 | 84 | 52 | . | H | 1581 | 958 | 658 | 405 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 9 | L | 552 | 335 | 230 | 141 | . | 29 | L | 3909 | 2369 | 1628 | 1002 |
| M | 432 | 262 | 180 | 111 | . | M | 3035 | 1839 | 1264 | 778 | ||
| Q | 312 | 189 | 130 | 80 | . | Q | 2181 | 1322 | 908 | 559 | ||
| H | 235 | 143 | 98 | 60 | . | H | 1677 | 1016 | 698 | 430 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 10 | L | 652 | 395 | 271 | 167 | . | 30 | L | 4158 | 2520 | 1732 | 1066 |
| M | 513 | 311 | 213 | 131 | . | M | 3289 | 1994 | 1370 | 843 | ||
| Q | 364 | 221 | 151 | 93 | . | Q | 2358 | 1429 | 982 | 604 | ||
| H | 288 | 174 | 119 | 74 | . | H | 1782 | 1080 | 742 | 457 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 11 | L | 772 | 468 | 321 | 198 | . | 31 | L | 4417 | 2677 | 1840 | 1132 |
| M | 604 | 366 | 251 | 155 | . | M | 3486 | 2113 | 1452 | 894 | ||
| Q | 427 | 259 | 177 | 109 | . | Q | 2473 | 1499 | 1030 | 634 | ||
| H | 331 | 200 | 137 | 85 | . | H | 1897 | 1150 | 790 | 486 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 12 | L | 883 | 535 | 367 | 226 | . | 32 | L | 4686 | 2840 | 1952 | 1201 |
| M | 691 | 419 | 287 | 177 | . | M | 3693 | 2238 | 1538 | 947 | ||
| Q | 489 | 296 | 203 | 125 | . | Q | 2670 | 1618 | 1112 | 684 | ||
| H | 374 | 227 | 155 | 96 | . | H | 2022 | 1226 | 842 | 518 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 13 | L | 1022 | 619 | 425 | 262 | . | 33 | L | 4965 | 3009 | 2068 | 1273 |
| M | 796 | 483 | 331 | 204 | . | M | 3909 | 2369 | 1628 | 1002 | ||
| Q | 580 | 352 | 241 | 149 | . | Q | 2805 | 1700 | 1168 | 719 | ||
| H | 427 | 259 | 177 | 109 | . | H | 2157 | 1307 | 898 | 553 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 14 | L | 1101 | 667 | 458 | 282 | . | 34 | L | 5253 | 3183 | 2188 | 1347 |
| M | 871 | 528 | 362 | 223 | . | M | 4134 | 2506 | 1722 | 1060 | ||
| Q | 621 | 376 | 258 | 159 | . | Q | 2949 | 1787 | 1228 | 756 | ||
| H | 468 | 283 | 194 | 120 | . | H | 2301 | 1394 | 958 | 590 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 15 | L | 1250 | 758 | 520 | 320 | . | 35 | L | 5529 | 3351 | 2303 | 1417 |
| M | 991 | 600 | 412 | 254 | . | M | 4343 | 2632 | 1809 | 1113 | ||
| Q | 703 | 426 | 292 | 180 | . | Q | 3081 | 1867 | 1283 | 790 | ||
| H | 530 | 321 | 220 | 136 | . | H | 2361 | 1431 | 983 | 605 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 16 | L | 1408 | 854 | 586 | 361 | . | 36 | L | 5836 | 3537 | 2431 | 1496 |
| M | 1082 | 656 | 450 | 277 | . | M | 4588 | 2780 | 1911 | 1176 | ||
| Q | 775 | 470 | 322 | 198 | . | Q | 3244 | 1966 | 1351 | 832 | ||
| H | 602 | 365 | 250 | 154 | . | H | 2524 | 1530 | 1051 | 647 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 17 | L | 1548 | 938 | 644 | 397 | . | 37 | L | 6153 | 3729 | 2563 | 1577 |
| M | 1212 | 734 | 504 | 310 | . | M | 4775 | 2894 | 1989 | 1224 | ||
| Q | 876 | 531 | 364 | 224 | . | Q | 3417 | 2071 | 1423 | 876 | ||
| H | 674 | 408 | 280 | 173 | . | H | 2625 | 1591 | 1093 | 673 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 18 | L | 1725 | 1046 | 718 | 442 | . | 38 | L | 6479 | 3927 | 2699 | 1661 |
| M | 1346 | 816 | 560 | 345 | . | M | 5039 | 3054 | 2099 | 1292 | ||
| Q | 948 | 574 | 394 | 243 | . | Q | 3599 | 2181 | 1499 | 923 | ||
| H | 746 | 452 | 310 | 191 | . | H | 2735 | 1658 | 1139 | 701 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 19 | L | 1903 | 1153 | 792 | 488 | . | 39 | L | 6743 | 4087 | 2809 | 1729 |
| M | 1500 | 909 | 624 | 384 | . | M | 5313 | 3220 | 2213 | 1362 | ||
| Q | 1063 | 644 | 442 | 272 | . | Q | 3791 | 2298 | 1579 | 972 | ||
| H | 813 | 493 | 338 | 208 | . | H | 2927 | 1774 | 1219 | 750 | ||
| - | - | - | - | - | - | . | - | - | - | - | - | - |
| 20 | L | 2061 | 1249 | 858 | 528 | . | 40 | L | 7089 | 4296 | 2953 | 1817 |
| M | 1600 | 970 | 666 | 410 | . | M | 5596 | 3391 | 2331 | 1435 | ||
| Q | 1159 | 702 | 482 | 297 | . | Q | 3993 | 2420 | 1663 | 1024 | ||
| H | 919 | 557 | 382 | 235 | . | H | 3057 | 1852 | 1273 | 784 |
