authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-01 00:07:41 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-03-01 00:07:41 -08:00
log0a785801a67e279de0d4619e201686dc84885a76
tree3b21716b114e886708d79fb02e339dccf6832686
parentb4d8be82ef92e32b38e2faee3c9de625d61a31b3

add otpauth test


2 files changed, 111 insertions(+), 1 deletions(-)

qrcode.zig+1-1
......@@ -729,7 +729,7 @@ fn generatorPolynomial(comptime n: usize) [n + 1]u8 {
729729
730730fn to_alpha(array: anytype) [array.len]u8 {
731731 var result: [array.len]u8 = array;
732 for (&result) |*x| x.* = @intCast(std.mem.indexOfScalar(u8, &GF, x.*).?);
732 for (&result) |*x| x.* = @intCast(std.mem.indexOfScalar(u8, &GF, x.*) orelse 0);
733733 return result;
734734}
735735
test.zig+110
......@@ -1070,3 +1070,113 @@ test {
10701070 else => unreachable,
10711071 }
10721072}
1073
1074test {
1075 const allocator = std.testing.allocator;
1076 const input = "otpauth://totp/ACME%20Co:john.doe@email.com?secret=HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ&algorithm=SHA256&digits=6&period=30&issuer=ACME%20Co";
1077 const version = qrcode.getMinVersion(.L, .latin1, input.len).?;
1078 switch (version) {
1079 inline 1...40 => |v| {
1080 const grid = qrcode.encode(.latin1, .L, v, input);
1081 const blocks = try grid.asBlockString2(allocator);
1082 defer allocator.free(blocks);
1083 try expect(blocks).toEqualString(
1084 \\█▀▀▀▀▀█ ▀█▄▄ ▀ █ █ ▄▀▀ ▀ ██▄█▄▀▀ ▄▀ █▀▀▀▀▀█|
1085 \\█ ███ █ █▄▄█▀▄ ▄▀█▄▀ █▀█▄█▄█ ▄ ▄▀ █▄ █ ███ █|
1086 \\█ ▀▀▀ █ ▀█▄ ▄▀██ █▄██▀▀▀█ ██ █▄ ▀ ▀▀▀ █ ▀▀▀ █|
1087 \\▀▀▀▀▀▀▀ ▀ ▀▄▀ ▀▄▀ █ █ ▀ █ █ █ █ ▀▄▀▄█ ▀▀▀▀▀▀▀|
1088 \\██▀█ ▄▀ ▀█ █▀ ▀ █ ▄ █▀▀█▀▄▀▄▀▄█ █▀▄▄█ ▄▀▀█ █|
1089 \\███▀▄ ▀ ▄▄ ▄▄▄▀█▄ ▀ ▄▀▄▄ █▀██ ▄ █▄▄▄ █ █▀█▀|
1090 \\▀▀ ▄▀ ▄▀▀█ █▄▄ █▀ ▄ ▀▄█ ▄▀ █▀█▄ ▀▄█▄▄▄▀ ▄|
1091 \\▄▀█▄ ▀▀███ ██ ▄█▀▀█ ▀▀▀ ██████▀█▀ ▀███▀▄█▄ |
1092 \\▀ ▀▀█▀▀█▀▀▀ █ ▀▀▄ ▀ ▄ █▄▀ █▄█ ▀█▀▄█ ▀ █ ▄█ ▄|
1093 \\█▄▄ ▀▄▄▀▀▄▀ ▄▄▀█▄ ▀▀▄█▀█ ▀▀ ▀█ ▀▀ █▀ ▀▄|
1094 \\█ ▄█▀▀▀█ ▀▀▀█▄ ▀▀▄██▀▀▀██▀▀█ █▄▄▄ ▀█▀▀▀██▄▄ |
1095 \\██▀▀█ ▀ █▀▀▄ █▄▀██ ▄█ ▀ █ ▄▀▀████▀█ █ ▀ █▄ ▀▀|
1096 \\▀█▀▀▀█▀▀█ █▀▀██▄ ▀▀▀▀▀▀▀▀▄▄ ▀ ▀ ▀▀█████▀█▄█▀|
1097 \\ ▄▀██▀▀▄▀█ ▀▄ ▄ ▀▀█ ███ █▄█▄█▀█▀ ▀ ▄▄▀ █▄▄|
1098 \\ █▀▄█▀ ▀ █ █▀▀█▄ ▀ ▀▄ ▀▀▀█▄█▀▀▀▀▄▀▀█▀ ██▀█ |
1099 \\██ ▄▄█▀█ ██▀ ▄▄▀▀█▄ ▀▀▀ █▀▀█▀ ▀ ▀ █ ▄█ ▀▀▄|
1100 \\ ▄ █ ▄▀▄▄ ▄ █ █▀▀█▀▄▀▀█▄▄▀▀▀█▄ ▄ ▀ ▀ ▄█ ▄|
1101 \\ ▄▄▄█ ▀█ ▄▀██ ▀▄▄▄▄████▀█ ▀▀▀ ▄▄▄▄ ▄██▄ █▀█▀|
1102 \\▀ ▀▀ ▀ █▄▄ ▀▀▄█ ▀▀ █▀▀▀███ ▄ ▀▀▄▀▀ █▀▀▀█▄▄▄█|
1103 \\█▀▀▀▀▀█ ▄ █▄ █▄ ▄▄ █ ▀ █ ▀▄█ █▄▄▄ ██ ▀ █ ▄ ▄|
1104 \\█ ███ █ ▄▄█ █ ▄ █ ▀███▀▀ █▄█ ███ ██▀▀▀ ▀█▀|
1105 \\█ ▀▀▀ █ █▄▄█▀▀ ██ █▀▄▀▄▀█ █▄▄ ▀▀█▀█▀ ▄▀▄▀▀ █|
1106 \\▀▀▀▀▀▀▀ ▀ ▀▀ ▀▀▀ ▀▀ ▀▀▀▀ ▀▀▀ ▀ |
1107 \\
1108 );
1109 const braille = try grid.asBrailleString(allocator);
1110 defer allocator.free(braille);
1111 try expect(braille).toEqualString(
1112 \\⡏⣭⡍⡇⣝⣲⢌⢘⢤⡸⢰⢭⣨⣸⢓⢓⠍⢰⡁⡏⣭⡍⡇|
1113 \\⠧⠭⠥⠇⠝⢆⠎⢟⠜⡞⡏⠍⡇⡟⡜⡆⢅⢍⡅⠧⠭⠥⠇|
1114 \\⣿⡽⡐⠅⠙⣘⢁⣁⢧⡂⠏⡹⣑⢱⢵⡇⡘⣕⣚⢰⢩⢧⠇|
1115 \\⡩⣄⠐⠥⣮⡝⣼⢒⡼⢥⠢⠵⢣⣮⣼⡽⡦⠠⣵⡷⣲⡁⠂|
1116 \\⣅⡉⠋⢝⡩⢅⠇⠉⢂⡡⣔⠸⢎⡼⡞⠨⠏⢾⠨⠜⡴⠣⡂|
1117 \\⣧⠴⡏⠍⡧⢍⢹⡢⣭⢚⡏⠍⡟⡩⢧⣷⡶⡌⡏⠍⣟⠲⠄|
1118 \\⢙⢭⡽⢍⢧⠸⡉⠛⡂⠭⡍⣭⡍⣖⣌⡬⡬⠹⢛⡻⠙⣞⡁|
1119 \\⣤⢋⣺⢥⢡⡼⢘⡩⢷⡈⠬⠆⢩⠽⡾⠉⠍⠎⢹⢁⡟⠽⡀|
1120 \\⢐⣘⡔⢵⢂⢴⡜⠸⣉⣋⣮⣽⢶⠩⠽⢂⣂⡁⣡⣄⢰⢧⠆|
1121 \\⡥⠬⠥⡅⢓⢢⡉⣞⢈⡁⡏⠍⡟⢇⡆⣍⣊⢡⡏⠍⡗⡒⡃|
1122 \\⡇⠿⠇⡇⣖⣣⠼⢰⡜⡤⡹⡻⡍⣜⡚⠠⢿⢧⠟⡩⡡⠝⡅|
1123 \\⠉⠉⠉⠁⠁⠉⠀⠈⠉⠀⠀⠉⠀⠉⠉⠀⠀⠀⠉⠁⠀⠁⠀|
1124 \\
1125 );
1126 const svg = try grid.asSvg(allocator);
1127 defer allocator.free(svg);
1128 try expect(svg).toEqualString(
1129 \\<svg xmlns="http://www.w3.org/2000/svg" width="470" height="460" viewBox="-1 -1 47 46" shape-rendering="crispEdges" stroke="#000">
1130 \\<rect x="-1" y="-1" width="47" height="46" fill="#fff" stroke="none" />
1131 \\<path d="M0,0 h7 M8,0 h2 M13,0 h1 M15,0 h1 M19,0 h1 M22,0 h2 M25,0 h1 M27,0 h2 M30,0 h1 M32,0 h2 M36,0 h1 M38,0 h7" />
1132 \\<path d="M0,1 h1 M6,1 h1 M9,1 h3 M15,1 h1 M19,1 h1 M21,1 h1 M27,1 h5 M35,1 h1 M38,1 h1 M44,1 h1" />
1133 \\<path d="M0,2 h1 M2,2 h3 M6,2 h1 M8,2 h1 M11,2 h2 M16,2 h2 M19,2 h1 M21,2 h3 M25,2 h1 M27,2 h1 M32,2 h1 M35,2 h1 M38,2 h1 M40,2 h3 M44,2 h1" />
1134 \\<path d="M0,3 h1 M2,3 h3 M6,3 h1 M8,3 h4 M13,3 h1 M15,3 h1 M17,3 h2 M21,3 h1 M23,3 h5 M29,3 h1 M31,3 h1 M35,3 h2 M38,3 h1 M40,3 h3 M44,3 h1" />
1135 \\<path d="M0,4 h1 M2,4 h3 M6,4 h1 M8,4 h2 M13,4 h3 M17,4 h1 M19,4 h6 M26,4 h2 M29,4 h1 M32,4 h1 M34,4 h3 M38,4 h1 M40,4 h3 M44,4 h1" />
1136 \\<path d="M0,5 h1 M6,5 h1 M9,5 h2 M12,5 h1 M14,5 h2 M17,5 h4 M24,5 h1 M26,5 h2 M29,5 h2 M38,5 h1 M44,5 h1" />
1137 \\<path d="M0,6 h7 M8,6 h1 M10,6 h1 M12,6 h1 M14,6 h1 M16,6 h1 M18,6 h1 M20,6 h1 M22,6 h1 M24,6 h1 M26,6 h1 M28,6 h1 M30,6 h1 M32,6 h1 M34,6 h1 M36,6 h1 M38,6 h7" />
1138 \\<path d="M11,7 h1 M15,7 h1 M18,7 h1 M20,7 h1 M24,7 h1 M26,7 h1 M28,7 h1 M30,7 h1 M33,7 h1 M35,7 h2 " />
1139 \\<path d="M0,8 h4 M6,8 h1 M8,8 h2 M11,8 h2 M14,8 h1 M16,8 h1 M20,8 h5 M26,8 h1 M28,8 h1 M30,8 h1 M33,8 h2 M37,8 h1 M40,8 h3 M44,8 h1" />
1140 \\<path d="M0,9 h2 M3,9 h1 M5,9 h1 M9,9 h1 M11,9 h1 M16,9 h1 M18,9 h1 M20,9 h1 M23,9 h1 M25,9 h1 M27,9 h1 M29,9 h2 M33,9 h1 M35,9 h3 M39,9 h1 M42,9 h1 M44,9 h1" />
1141 \\<path d="M0,10 h4 M6,10 h1 M16,10 h2 M20,10 h1 M23,10 h1 M27,10 h4 M34,10 h1 M39,10 h1 M41,10 h4" />
1142 \\<path d="M0,11 h3 M4,11 h1 M10,11 h2 M13,11 h3 M17,11 h2 M22,11 h1 M24,11 h2 M27,11 h1 M29,11 h2 M32,11 h1 M34,11 h4 M39,11 h1 M41,11 h1 M43,11 h1 " />
1143 \\<path d="M0,12 h2 M6,12 h1 M9,12 h3 M13,12 h1 M17,12 h2 M22,12 h1 M24,12 h1 M27,12 h1 M29,12 h3 M36,12 h1 M38,12 h1 M42,12 h1 " />
1144 \\<path d="M5,13 h1 M8,13 h1 M11,13 h1 M13,13 h3 M17,13 h1 M20,13 h1 M23,13 h2 M26,13 h1 M29,13 h1 M31,13 h2 M37,13 h5 M44,13 h1" />
1145 \\<path d="M1,14 h2 M6,14 h5 M12,14 h2 M16,14 h4 M21,14 h3 M25,14 h9 M35,14 h5 M41,14 h1 " />
1146 \\<path d="M0,15 h1 M2,15 h2 M8,15 h3 M12,15 h2 M15,15 h2 M19,15 h1 M25,15 h6 M32,15 h1 M36,15 h3 M40,15 h3 " />
1147 \\<path d="M0,16 h1 M2,16 h9 M12,16 h1 M14,16 h2 M18,16 h1 M23,16 h1 M25,16 h1 M27,16 h1 M29,16 h1 M31,16 h3 M35,16 h1 M37,16 h1 M39,16 h1 M42,16 h1 " />
1148 \\<path d="M4,17 h1 M7,17 h1 M12,17 h1 M16,17 h1 M21,17 h1 M23,17 h2 M27,17 h3 M32,17 h1 M34,17 h2 M39,17 h1 M41,17 h2 M44,17 h1" />
1149 \\<path d="M0,18 h1 M6,18 h1 M9,18 h2 M12,18 h1 M19,18 h2 M23,18 h2 M26,18 h3 M31,18 h2 M34,18 h2 M37,18 h2 M40,18 h2 M43,18 h1 " />
1150 \\<path d="M0,19 h3 M7,19 h2 M11,19 h1 M17,19 h2 M20,19 h2 M25,19 h2 M28,19 h1 M35,19 h1 M40,19 h1 M44,19 h1" />
1151 \\<path d="M0,20 h1 M4,20 h5 M10,20 h4 M16,20 h2 M19,20 h10 M30,20 h1 M35,20 h7 " />
1152 \\<path d="M0,21 h1 M3,21 h2 M8,21 h1 M13,21 h2 M18,21 h3 M24,21 h2 M28,21 h1 M30,21 h4 M36,21 h1 M40,21 h4 " />
1153 \\<path d="M0,22 h5 M6,22 h1 M8,22 h3 M13,22 h1 M15,22 h3 M20,22 h1 M22,22 h1 M24,22 h1 M27,22 h8 M36,22 h1 M38,22 h1 M40,22 h1 M43,22 h2" />
1154 \\<path d="M0,23 h2 M4,23 h1 M8,23 h1 M11,23 h1 M13,23 h2 M16,23 h2 M19,23 h2 M24,23 h1 M26,23 h1 M29,23 h4 M34,23 h1 M36,23 h1 M40,23 h2 " />
1155 \\<path d="M0,24 h9 M11,24 h5 M18,24 h8 M29,24 h1 M31,24 h1 M33,24 h9 M43,24 h2" />
1156 \\<path d="M1,25 h1 M5,25 h1 M8,25 h1 M11,25 h1 M14,25 h3 M26,25 h2 M35,25 h5 M41,25 h3 " />
1157 \\<path d="M2,26 h5 M8,26 h2 M11,26 h1 M18,26 h3 M22,26 h3 M26,26 h1 M28,26 h1 M30,26 h4 M35,26 h1 M39,26 h1 M42,26 h1 " />
1158 \\<path d="M1,27 h1 M3,27 h2 M7,27 h1 M9,27 h1 M12,27 h1 M16,27 h1 M20,27 h1 M22,27 h3 M26,27 h5 M32,27 h1 M37,27 h2 M42,27 h3" />
1159 \\<path d="M2,28 h2 M5,28 h2 M8,28 h1 M11,28 h1 M13,28 h4 M19,28 h1 M21,28 h1 M24,28 h4 M29,28 h5 M35,28 h4 M40,28 h4 " />
1160 \\<path d="M2,29 h1 M4,29 h2 M11,29 h1 M13,29 h1 M16,29 h2 M22,29 h1 M27,29 h3 M34,29 h1 M37,29 h1 M40,29 h2 M43,29 h1 " />
1161 \\<path d="M0,30 h2 M5,30 h3 M9,30 h3 M15,30 h3 M20,30 h3 M25,30 h5 M32,30 h1 M34,30 h1 M37,30 h1 M40,30 h1 M42,30 h2 " />
1162 \\<path d="M0,31 h2 M3,31 h3 M7,31 h1 M9,31 h2 M13,31 h2 M17,31 h2 M25,31 h1 M28,31 h1 M37,31 h1 M39,31 h2 M44,31 h1" />
1163 \\<path d="M3,32 h1 M6,32 h1 M13,32 h1 M15,32 h5 M21,32 h3 M26,32 h4 M34,32 h1 M36,32 h1 M42,32 h1 " />
1164 \\<path d="M1,33 h1 M3,33 h1 M5,33 h1 M7,33 h2 M11,33 h1 M13,33 h1 M15,33 h1 M18,33 h1 M20,33 h1 M23,33 h3 M29,33 h2 M32,33 h1 M41,33 h2 M44,33 h1" />
1165 \\<path d="M4,34 h1 M6,34 h2 M10,34 h3 M15,34 h1 M20,34 h6 M27,34 h3 M37,34 h2 M41,34 h4" />
1166 \\<path d="M1,35 h4 M7,35 h1 M9,35 h1 M11,35 h2 M16,35 h8 M25,35 h1 M31,35 h4 M36,35 h4 M41,35 h1 M43,35 h1 " />
1167 \\<path d="M0,36 h1 M3,36 h2 M6,36 h1 M8,36 h1 M12,36 h2 M15,36 h1 M17,36 h2 M20,36 h7 M30,36 h2 M33,36 h2 M36,36 h5 M44,36 h1" />
1168 \\<path d="M8,37 h3 M14,37 h2 M20,37 h1 M24,37 h3 M28,37 h1 M32,37 h1 M36,37 h1 M40,37 h5" />
1169 \\<path d="M0,38 h7 M11,38 h1 M14,38 h1 M20,38 h1 M22,38 h1 M24,38 h1 M26,38 h1 M28,38 h1 M30,38 h1 M35,38 h2 M38,38 h1 M40,38 h1 " />
1170 \\<path d="M0,39 h1 M6,39 h1 M9,39 h1 M11,39 h2 M14,39 h2 M17,39 h2 M20,39 h1 M24,39 h1 M27,39 h2 M30,39 h4 M35,39 h2 M40,39 h1 M42,39 h1 M44,39 h1" />
1171 \\<path d="M0,40 h1 M2,40 h3 M6,40 h1 M10,40 h1 M13,40 h1 M17,40 h1 M20,40 h6 M27,40 h1 M29,40 h1 M32,40 h3 M36,40 h5 M42,40 h3" />
1172 \\<path d="M0,41 h1 M2,41 h3 M6,41 h1 M8,41 h3 M13,41 h1 M15,41 h1 M17,41 h1 M21,41 h3 M27,41 h3 M32,41 h3 M36,41 h2 M43,41 h1 " />
1173 \\<path d="M0,42 h1 M2,42 h3 M6,42 h1 M8,42 h1 M11,42 h3 M15,42 h2 M18,42 h2 M21,42 h1 M23,42 h2 M26,42 h1 M31,42 h6 M39,42 h1 M41,42 h2 M44,42 h1" />
1174 \\<path d="M0,43 h1 M6,43 h1 M8,43 h4 M15,43 h2 M18,43 h1 M20,43 h1 M22,43 h1 M24,43 h1 M26,43 h3 M33,43 h1 M35,43 h1 M38,43 h1 M40,43 h1 M44,43 h1" />
1175 \\<path d="M0,44 h7 M8,44 h1 M10,44 h2 M15,44 h3 M22,44 h2 M26,44 h4 M36,44 h3 M42,44 h1 " />
1176 \\</svg>
1177 \\
1178 );
1179 },
1180 else => unreachable,
1181 }
1182}