diff --git a/Misc/QR.Designer.cs b/Misc/QR.Designer.cs
new file mode 100644
index 000000000..6cc01d468
--- /dev/null
+++ b/Misc/QR.Designer.cs
@@ -0,0 +1,70 @@
+namespace PKHeX
+{
+ partial class QR
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(QR));
+ this.PB_QR = new System.Windows.Forms.PictureBox();
+ ((System.ComponentModel.ISupportInitialize)(this.PB_QR)).BeginInit();
+ this.SuspendLayout();
+ //
+ // PB_QR
+ //
+ this.PB_QR.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.PB_QR.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.PB_QR.Location = new System.Drawing.Point(2, 1);
+ this.PB_QR.Name = "PB_QR";
+ this.PB_QR.Size = new System.Drawing.Size(300, 300);
+ this.PB_QR.TabIndex = 0;
+ this.PB_QR.TabStop = false;
+ //
+ // QR
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(304, 302);
+ this.Controls.Add(this.PB_QR);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "QR";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "PKHeX QR Code";
+ ((System.ComponentModel.ISupportInitialize)(this.PB_QR)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.PictureBox PB_QR;
+ }
+}
\ No newline at end of file
diff --git a/Misc/QR.cs b/Misc/QR.cs
new file mode 100644
index 000000000..3ab2c6e2f
--- /dev/null
+++ b/Misc/QR.cs
@@ -0,0 +1,1223 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace PKHeX
+{
+ public partial class QR : Form
+ {
+ public QR(byte[] data)
+ {
+ InitializeComponent();
+ string server = "http://lunarcookies.github.io/b1s1.html#";
+ var qrdata = data.Reverse().Select( x => Convert.ToString(x, 2).PadLeft( 8, '0' ));
+ QRCodeGenerator qrGenerator = new QRCodeGenerator();
+ QRCodeGenerator.QRCode qrCode = qrGenerator.CreateQrCode(server + qrdata.ToString(), QRCodeGenerator.ECCLevel.Q);
+ PB_QR.BackgroundImage = qrCode.GetGraphic(10);
+ }
+ }
+ public class QRCodeGenerator
+ {
+ private char[] alphanumEncTable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':' };
+ private int[] capacityBaseValues = { 41, 25, 17, 10, 34, 20, 14, 8, 27, 16, 11, 7, 17, 10, 7, 4, 77, 47, 32, 20, 63, 38, 26, 16, 48, 29, 20, 12, 34, 20, 14, 8, 127, 77, 53, 32, 101, 61, 42, 26, 77, 47, 32, 20, 58, 35, 24, 15, 187, 114, 78, 48, 149, 90, 62, 38, 111, 67, 46, 28, 82, 50, 34, 21, 255, 154, 106, 65, 202, 122, 84, 52, 144, 87, 60, 37, 106, 64, 44, 27, 322, 195, 134, 82, 255, 154, 106, 65, 178, 108, 74, 45, 139, 84, 58, 36, 370, 224, 154, 95, 293, 178, 122, 75, 207, 125, 86, 53, 154, 93, 64, 39, 461, 279, 192, 118, 365, 221, 152, 93, 259, 157, 108, 66, 202, 122, 84, 52, 552, 335, 230, 141, 432, 262, 180, 111, 312, 189, 130, 80, 235, 143, 98, 60, 652, 395, 271, 167, 513, 311, 213, 131, 364, 221, 151, 93, 288, 174, 119, 74, 772, 468, 321, 198, 604, 366, 251, 155, 427, 259, 177, 109, 331, 200, 137, 85, 883, 535, 367, 226, 691, 419, 287, 177, 489, 296, 203, 125, 374, 227, 155, 96, 1022, 619, 425, 262, 796, 483, 331, 204, 580, 352, 241, 149, 427, 259, 177, 109, 1101, 667, 458, 282, 871, 528, 362, 223, 621, 376, 258, 159, 468, 283, 194, 120, 1250, 758, 520, 320, 991, 600, 412, 254, 703, 426, 292, 180, 530, 321, 220, 136, 1408, 854, 586, 361, 1082, 656, 450, 277, 775, 470, 322, 198, 602, 365, 250, 154, 1548, 938, 644, 397, 1212, 734, 504, 310, 876, 531, 364, 224, 674, 408, 280, 173, 1725, 1046, 718, 442, 1346, 816, 560, 345, 948, 574, 394, 243, 746, 452, 310, 191, 1903, 1153, 792, 488, 1500, 909, 624, 384, 1063, 644, 442, 272, 813, 493, 338, 208, 2061, 1249, 858, 528, 1600, 970, 666, 410, 1159, 702, 482, 297, 919, 557, 382, 235, 2232, 1352, 929, 572, 1708, 1035, 711, 438, 1224, 742, 509, 314, 969, 587, 403, 248, 2409, 1460, 1003, 618, 1872, 1134, 779, 480, 1358, 823, 565, 348, 1056, 640, 439, 270, 2620, 1588, 1091, 672, 2059, 1248, 857, 528, 1468, 890, 611, 376, 1108, 672, 461, 284, 2812, 1704, 1171, 721, 2188, 1326, 911, 561, 1588, 963, 661, 407, 1228, 744, 511, 315, 3057, 1853, 1273, 784, 2395, 1451, 997, 614, 1718, 1041, 715, 440, 1286, 779, 535, 330, 3283, 1990, 1367, 842, 2544, 1542, 1059, 652, 1804, 1094, 751, 462, 1425, 864, 593, 365, 3517, 2132, 1465, 902, 2701, 1637, 1125, 692, 1933, 1172, 805, 496, 1501, 910, 625, 385, 3669, 2223, 1528, 940, 2857, 1732, 1190, 732, 2085, 1263, 868, 534, 1581, 958, 658, 405, 3909, 2369, 1628, 1002, 3035, 1839, 1264, 778, 2181, 1322, 908, 559, 1677, 1016, 698, 430, 4158, 2520, 1732, 1066, 3289, 1994, 1370, 843, 2358, 1429, 982, 604, 1782, 1080, 742, 457, 4417, 2677, 1840, 1132, 3486, 2113, 1452, 894, 2473, 1499, 1030, 634, 1897, 1150, 790, 486, 4686, 2840, 1952, 1201, 3693, 2238, 1538, 947, 2670, 1618, 1112, 684, 2022, 1226, 842, 518, 4965, 3009, 2068, 1273, 3909, 2369, 1628, 1002, 2805, 1700, 1168, 719, 2157, 1307, 898, 553, 5253, 3183, 2188, 1347, 4134, 2506, 1722, 1060, 2949, 1787, 1228, 756, 2301, 1394, 958, 590, 5529, 3351, 2303, 1417, 4343, 2632, 1809, 1113, 3081, 1867, 1283, 790, 2361, 1431, 983, 605, 5836, 3537, 2431, 1496, 4588, 2780, 1911, 1176, 3244, 1966, 1351, 832, 2524, 1530, 1051, 647, 6153, 3729, 2563, 1577, 4775, 2894, 1989, 1224, 3417, 2071, 1423, 876, 2625, 1591, 1093, 673, 6479, 3927, 2699, 1661, 5039, 3054, 2099, 1292, 3599, 2181, 1499, 923, 2735, 1658, 1139, 701, 6743, 4087, 2809, 1729, 5313, 3220, 2213, 1362, 3791, 2298, 1579, 972, 2927, 1774, 1219, 750, 7089, 4296, 2953, 1817, 5596, 3391, 2331, 1435, 3993, 2420, 1663, 1024, 3057, 1852, 1273, 784 };
+ private int[] capacityECCBaseValues = { 19, 7, 1, 19, 0, 0, 16, 10, 1, 16, 0, 0, 13, 13, 1, 13, 0, 0, 9, 17, 1, 9, 0, 0, 34, 10, 1, 34, 0, 0, 28, 16, 1, 28, 0, 0, 22, 22, 1, 22, 0, 0, 16, 28, 1, 16, 0, 0, 55, 15, 1, 55, 0, 0, 44, 26, 1, 44, 0, 0, 34, 18, 2, 17, 0, 0, 26, 22, 2, 13, 0, 0, 80, 20, 1, 80, 0, 0, 64, 18, 2, 32, 0, 0, 48, 26, 2, 24, 0, 0, 36, 16, 4, 9, 0, 0, 108, 26, 1, 108, 0, 0, 86, 24, 2, 43, 0, 0, 62, 18, 2, 15, 2, 16, 46, 22, 2, 11, 2, 12, 136, 18, 2, 68, 0, 0, 108, 16, 4, 27, 0, 0, 76, 24, 4, 19, 0, 0, 60, 28, 4, 15, 0, 0, 156, 20, 2, 78, 0, 0, 124, 18, 4, 31, 0, 0, 88, 18, 2, 14, 4, 15, 66, 26, 4, 13, 1, 14, 194, 24, 2, 97, 0, 0, 154, 22, 2, 38, 2, 39, 110, 22, 4, 18, 2, 19, 86, 26, 4, 14, 2, 15, 232, 30, 2, 116, 0, 0, 182, 22, 3, 36, 2, 37, 132, 20, 4, 16, 4, 17, 100, 24, 4, 12, 4, 13, 274, 18, 2, 68, 2, 69, 216, 26, 4, 43, 1, 44, 154, 24, 6, 19, 2, 20, 122, 28, 6, 15, 2, 16, 324, 20, 4, 81, 0, 0, 254, 30, 1, 50, 4, 51, 180, 28, 4, 22, 4, 23, 140, 24, 3, 12, 8, 13, 370, 24, 2, 92, 2, 93, 290, 22, 6, 36, 2, 37, 206, 26, 4, 20, 6, 21, 158, 28, 7, 14, 4, 15, 428, 26, 4, 107, 0, 0, 334, 22, 8, 37, 1, 38, 244, 24, 8, 20, 4, 21, 180, 22, 12, 11, 4, 12, 461, 30, 3, 115, 1, 116, 365, 24, 4, 40, 5, 41, 261, 20, 11, 16, 5, 17, 197, 24, 11, 12, 5, 13, 523, 22, 5, 87, 1, 88, 415, 24, 5, 41, 5, 42, 295, 30, 5, 24, 7, 25, 223, 24, 11, 12, 7, 13, 589, 24, 5, 98, 1, 99, 453, 28, 7, 45, 3, 46, 325, 24, 15, 19, 2, 20, 253, 30, 3, 15, 13, 16, 647, 28, 1, 107, 5, 108, 507, 28, 10, 46, 1, 47, 367, 28, 1, 22, 15, 23, 283, 28, 2, 14, 17, 15, 721, 30, 5, 120, 1, 121, 563, 26, 9, 43, 4, 44, 397, 28, 17, 22, 1, 23, 313, 28, 2, 14, 19, 15, 795, 28, 3, 113, 4, 114, 627, 26, 3, 44, 11, 45, 445, 26, 17, 21, 4, 22, 341, 26, 9, 13, 16, 14, 861, 28, 3, 107, 5, 108, 669, 26, 3, 41, 13, 42, 485, 30, 15, 24, 5, 25, 385, 28, 15, 15, 10, 16, 932, 28, 4, 116, 4, 117, 714, 26, 17, 42, 0, 0, 512, 28, 17, 22, 6, 23, 406, 30, 19, 16, 6, 17, 1006, 28, 2, 111, 7, 112, 782, 28, 17, 46, 0, 0, 568, 30, 7, 24, 16, 25, 442, 24, 34, 13, 0, 0, 1094, 30, 4, 121, 5, 122, 860, 28, 4, 47, 14, 48, 614, 30, 11, 24, 14, 25, 464, 30, 16, 15, 14, 16, 1174, 30, 6, 117, 4, 118, 914, 28, 6, 45, 14, 46, 664, 30, 11, 24, 16, 25, 514, 30, 30, 16, 2, 17, 1276, 26, 8, 106, 4, 107, 1000, 28, 8, 47, 13, 48, 718, 30, 7, 24, 22, 25, 538, 30, 22, 15, 13, 16, 1370, 28, 10, 114, 2, 115, 1062, 28, 19, 46, 4, 47, 754, 28, 28, 22, 6, 23, 596, 30, 33, 16, 4, 17, 1468, 30, 8, 122, 4, 123, 1128, 28, 22, 45, 3, 46, 808, 30, 8, 23, 26, 24, 628, 30, 12, 15, 28, 16, 1531, 30, 3, 117, 10, 118, 1193, 28, 3, 45, 23, 46, 871, 30, 4, 24, 31, 25, 661, 30, 11, 15, 31, 16, 1631, 30, 7, 116, 7, 117, 1267, 28, 21, 45, 7, 46, 911, 30, 1, 23, 37, 24, 701, 30, 19, 15, 26, 16, 1735, 30, 5, 115, 10, 116, 1373, 28, 19, 47, 10, 48, 985, 30, 15, 24, 25, 25, 745, 30, 23, 15, 25, 16, 1843, 30, 13, 115, 3, 116, 1455, 28, 2, 46, 29, 47, 1033, 30, 42, 24, 1, 25, 793, 30, 23, 15, 28, 16, 1955, 30, 17, 115, 0, 0, 1541, 28, 10, 46, 23, 47, 1115, 30, 10, 24, 35, 25, 845, 30, 19, 15, 35, 16, 2071, 30, 17, 115, 1, 116, 1631, 28, 14, 46, 21, 47, 1171, 30, 29, 24, 19, 25, 901, 30, 11, 15, 46, 16, 2191, 30, 13, 115, 6, 116, 1725, 28, 14, 46, 23, 47, 1231, 30, 44, 24, 7, 25, 961, 30, 59, 16, 1, 17, 2306, 30, 12, 121, 7, 122, 1812, 28, 12, 47, 26, 48, 1286, 30, 39, 24, 14, 25, 986, 30, 22, 15, 41, 16, 2434, 30, 6, 121, 14, 122, 1914, 28, 6, 47, 34, 48, 1354, 30, 46, 24, 10, 25, 1054, 30, 2, 15, 64, 16, 2566, 30, 17, 122, 4, 123, 1992, 28, 29, 46, 14, 47, 1426, 30, 49, 24, 10, 25, 1096, 30, 24, 15, 46, 16, 2702, 30, 4, 122, 18, 123, 2102, 28, 13, 46, 32, 47, 1502, 30, 48, 24, 14, 25, 1142, 30, 42, 15, 32, 16, 2812, 30, 20, 117, 4, 118, 2216, 28, 40, 47, 7, 48, 1582, 30, 43, 24, 22, 25, 1222, 30, 10, 15, 67, 16, 2956, 30, 19, 118, 6, 119, 2334, 28, 18, 47, 31, 48, 1666, 30, 34, 24, 34, 25, 1276, 30, 20, 15, 61, 16 };
+ private int[] alignmentPatternBaseValues = { 0, 0, 0, 0, 0, 0, 0, 6, 18, 0, 0, 0, 0, 0, 6, 22, 0, 0, 0, 0, 0, 6, 26, 0, 0, 0, 0, 0, 6, 30, 0, 0, 0, 0, 0, 6, 34, 0, 0, 0, 0, 0, 6, 22, 38, 0, 0, 0, 0, 6, 24, 42, 0, 0, 0, 0, 6, 26, 46, 0, 0, 0, 0, 6, 28, 50, 0, 0, 0, 0, 6, 30, 54, 0, 0, 0, 0, 6, 32, 58, 0, 0, 0, 0, 6, 34, 62, 0, 0, 0, 0, 6, 26, 46, 66, 0, 0, 0, 6, 26, 48, 70, 0, 0, 0, 6, 26, 50, 74, 0, 0, 0, 6, 30, 54, 78, 0, 0, 0, 6, 30, 56, 82, 0, 0, 0, 6, 30, 58, 86, 0, 0, 0, 6, 34, 62, 90, 0, 0, 0, 6, 28, 50, 72, 94, 0, 0, 6, 26, 50, 74, 98, 0, 0, 6, 30, 54, 78, 102, 0, 0, 6, 28, 54, 80, 106, 0, 0, 6, 32, 58, 84, 110, 0, 0, 6, 30, 58, 86, 114, 0, 0, 6, 34, 62, 90, 118, 0, 0, 6, 26, 50, 74, 98, 122, 0, 6, 30, 54, 78, 102, 126, 0, 6, 26, 52, 78, 104, 130, 0, 6, 30, 56, 82, 108, 134, 0, 6, 34, 60, 86, 112, 138, 0, 6, 30, 58, 86, 114, 142, 0, 6, 34, 62, 90, 118, 146, 0, 6, 30, 54, 78, 102, 126, 150, 6, 24, 50, 76, 102, 128, 154, 6, 28, 54, 80, 106, 132, 158, 6, 32, 58, 84, 110, 136, 162, 6, 26, 54, 82, 110, 138, 166, 6, 30, 58, 86, 114, 142, 170 };
+ private int[] remainderBits = { 0, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0 };
+
+ private List alignmentPatternTable;
+ private List capacityECCTable;
+ private List capacityTable;
+ private List galoisField;
+ private Dictionary alphanumEncDict;
+
+ public QRCodeGenerator()
+ {
+ CreateAntilogTable();
+ CreateAlphanumEncDict();
+ CreateCapacityTable();
+ CreateCapacityECCTable();
+ CreateAlignmentPatternTable();
+ }
+ public QRCode CreateQrCode(string plainText, ECCLevel eccLevel)
+ {
+ var encoding = GetEncodingFromPlaintext(plainText);
+ var version = GetVersion(plainText, encoding, eccLevel);
+
+ var modeIndicator = DecToBin((int)encoding, 4);
+ var countIndicator = DecToBin(plainText.Length, GetCountIndicatorLength(version, encoding));
+ var bitString = modeIndicator + countIndicator;
+
+ var codedText = PlainTextToBinary(plainText, encoding);
+ bitString += codedText;
+
+ //Fill up data code word
+ var eccInfo = capacityECCTable.Where(x => x.Version == version && x.ErrorCorrectionLevel.Equals(eccLevel)).Single();
+ var dataLength = eccInfo.TotalDataCodewords * 8;
+ var lengthDiff = dataLength - bitString.Length;
+ if (lengthDiff > 0)
+ bitString += new string('0', Math.Min(lengthDiff, 4));
+ if ((bitString.Length % 8) != 0)
+ bitString += new string('0', 8 - (bitString.Length % 8));
+ while (bitString.Length < dataLength)
+ bitString += "1110110000010001";
+ if (bitString.Length > dataLength)
+ bitString = bitString.Substring(0, dataLength);
+
+ //Calculate error correction words
+ List codeWordWithECC = new List();
+ for (int i = 0; i < eccInfo.BlocksInGroup1; i++)
+ {
+ var bitStr = bitString.Substring(i * eccInfo.CodewordsInGroup1 * 8, eccInfo.CodewordsInGroup1 * 8);
+ codeWordWithECC.Add(new CodewordBlock()
+ {
+ BitString = bitStr,
+ BlockNumber = i + 1,
+ GroupNumber = 1,
+ CodeWords = BinaryStringToBitBlockList(bitStr),
+ ECCWords = CalculateECCWords(bitStr, eccInfo)
+ });
+ }
+ bitString = bitString.Substring(eccInfo.BlocksInGroup1 * eccInfo.CodewordsInGroup1 * 8);
+ for (int i = 0; i < eccInfo.BlocksInGroup2; i++)
+ {
+ var bitStr = bitString.Substring(i * eccInfo.CodewordsInGroup2 * 8, eccInfo.CodewordsInGroup2 * 8);
+ codeWordWithECC.Add(new CodewordBlock()
+ {
+ BitString = bitStr,
+ BlockNumber = i + 1,
+ GroupNumber = 2,
+ CodeWords = BinaryStringToBitBlockList(bitStr),
+ ECCWords = CalculateECCWords(bitStr, eccInfo)
+ });
+ }
+
+
+ //Interleave code words
+ StringBuilder interleavedWordsSb = new StringBuilder();
+ for (int i = 0; i < Math.Max(eccInfo.CodewordsInGroup1, eccInfo.CodewordsInGroup2); i++)
+ {
+ foreach (var codeBlock in codeWordWithECC)
+ if (codeBlock.CodeWords.Count > i)
+ interleavedWordsSb.Append(codeBlock.CodeWords[i]);
+ }
+
+
+ for (int i = 0; i < eccInfo.ECCPerBlock; i++)
+ {
+ foreach (var codeBlock in codeWordWithECC)
+ interleavedWordsSb.Append(codeBlock.ECCWords[i]);
+ }
+ interleavedWordsSb.Append(new string('0', remainderBits[version - 1]));
+ var interleavedData = interleavedWordsSb.ToString();
+ //Place interleaved data on module matrix
+ QRCode qr = new QRCode(version);
+ List blockedModules = new List();
+ ModulePlacer.PlaceFinderPatterns(ref qr, ref blockedModules);
+ ModulePlacer.ReserveSeperatorAreas(qr.ModuleMatrix.Count, ref blockedModules);
+ ModulePlacer.PlaceAlignmentPatterns(ref qr, alignmentPatternTable.Where(x => x.Version == version).Select(x => x.PatternPositions).First(), ref blockedModules);
+ ModulePlacer.PlaceTimingPatterns(ref qr, ref blockedModules);
+ ModulePlacer.PlaceDarkModule(ref qr, version, ref blockedModules);
+ ModulePlacer.ReserveVersionAreas(qr.ModuleMatrix.Count, version, ref blockedModules);
+ ModulePlacer.PlaceDataWords(ref qr, interleavedData, ref blockedModules);
+ var maskVersion = ModulePlacer.MaskCode(ref qr, version, ref blockedModules);
+ var formatStr = GetFormatString(eccLevel, maskVersion);
+
+ ModulePlacer.PlaceFormat(ref qr, formatStr);
+ if (version >= 7)
+ {
+ var versionString = GetVersionString(version);
+ ModulePlacer.PlaceVersion(ref qr, versionString);
+ }
+ ModulePlacer.AddQuietZone(ref qr);
+ return qr;
+ }
+
+ private string GetFormatString(ECCLevel level, int maskVersion)
+ {
+ var generator = "10100110111";
+ var fStrMask = "101010000010010";
+
+ var fStr = (level == ECCLevel.L) ? "01" : (level == ECCLevel.M) ? "00" : (level == ECCLevel.Q) ? "11" : "10";
+ fStr += DecToBin(maskVersion, 3);
+ var fStrEcc = fStr.PadRight(15, '0').TrimStart('0');
+ while (fStrEcc.Length > 10)
+ {
+ StringBuilder sb = new StringBuilder();
+ generator = generator.PadRight(fStrEcc.Length, '0');
+ for (int i = 0; i < fStrEcc.Length; i++)
+ sb.Append((Convert.ToInt32(fStrEcc[i]) ^ Convert.ToInt32(generator[i])).ToString());
+ fStrEcc = sb.ToString().TrimStart('0');
+ }
+ fStrEcc = fStrEcc.PadLeft(10, '0');
+ fStr += fStrEcc;
+
+ StringBuilder sbMask = new StringBuilder();
+ for (int i = 0; i < fStr.Length; i++)
+ sbMask.Append((Convert.ToInt32(fStr[i]) ^ Convert.ToInt32(fStrMask[i])).ToString());
+ return sbMask.ToString();
+ }
+ private string GetVersionString(int version)
+ {
+ var generator = "1111100100101";
+
+ var vStr = DecToBin(version, 6);
+ var vStrEcc = vStr.PadRight(18, '0').TrimStart('0');
+ while (vStrEcc.Length > 12)
+ {
+ StringBuilder sb = new StringBuilder();
+ generator = generator.PadRight(vStrEcc.Length, '0');
+ for (int i = 0; i < vStrEcc.Length; i++)
+ sb.Append((Convert.ToInt32(vStrEcc[i]) ^ Convert.ToInt32(generator[i])).ToString());
+ vStrEcc = sb.ToString().TrimStart('0');
+ }
+ vStrEcc = vStrEcc.PadLeft(12, '0');
+ vStr += vStrEcc;
+
+ return vStr;
+ }
+ private static class ModulePlacer
+ {
+ public static void AddQuietZone(ref QRCode qrCode)
+ {
+ bool[] quietLine = new bool[qrCode.ModuleMatrix.Count + 8];
+ for (int i = 0; i < quietLine.Length; i++)
+ quietLine[i] = false;
+ for (int i = 0; i < 4; i++)
+ qrCode.ModuleMatrix.Insert(0, new BitArray(quietLine));
+ for (int i = 0; i < 4; i++)
+ qrCode.ModuleMatrix.Add(new BitArray(quietLine));
+ for (int i = 4; i < qrCode.ModuleMatrix.Count - 4; i++)
+ {
+ bool[] quietPart = new bool[4] { false, false, false, false };
+ List tmpLine = new List(quietPart);
+ foreach (bool module in qrCode.ModuleMatrix[i])
+ tmpLine.Add(module);
+ tmpLine.AddRange(quietPart);
+ qrCode.ModuleMatrix[i] = new BitArray(tmpLine.ToArray());
+ }
+ }
+
+ public static void PlaceVersion(ref QRCode qrCode, string versionStr)
+ {
+ var size = qrCode.ModuleMatrix.Count;
+ var vStr = new string(versionStr.Reverse().ToArray());
+
+ for (int x = 0; x < 6; x++)
+ {
+ for (int y = 0; y < 3; y++)
+ {
+ qrCode.ModuleMatrix[y + size - 11][x] = vStr[x * 3 + y] == '1' ? true : false;
+ qrCode.ModuleMatrix[x][y + size - 11] = vStr[x * 3 + y] == '1' ? true : false;
+ }
+ }
+ }
+
+ public static void PlaceFormat(ref QRCode qrCode, string formatStr)
+ {
+ var size = qrCode.ModuleMatrix.Count;
+ var fStr = new string(formatStr.Reverse().ToArray());
+ int[,] modules = new int[15, 4] { { 8, 0, size - 1, 8 }, { 8, 1, size - 2, 8 }, { 8, 2, size - 3, 8 }, { 8, 3, size - 4, 8 }, { 8, 4, size - 5, 8 }, { 8, 5, size - 6, 8 }, { 8, 7, size - 7, 8 }, { 8, 8, size - 8, 8 }, { 7, 8, 8, size - 7 }, { 5, 8, 8, size - 6 }, { 4, 8, 8, size - 5 }, { 3, 8, 8, size - 4 }, { 2, 8, 8, size - 3 }, { 1, 8, 8, size - 2 }, { 0, 8, 8, size - 1 } };
+ for (int i = 0; i < 15; i++)
+ {
+ var p1 = new Point(modules[i, 0], modules[i, 1]);
+ var p2 = new Point(modules[i, 2], modules[i, 3]);
+ qrCode.ModuleMatrix[p1.Y][p1.X] = fStr[i] == '1' ? true : false;
+ qrCode.ModuleMatrix[p2.Y][p2.X] = fStr[i] == '1' ? true : false;
+ }
+ }
+
+ public static int MaskCode(ref QRCode qrCode, int version, ref List blockedModules)
+ {
+ var patternName = string.Empty;
+ var patternScore = 0;
+
+ var size = qrCode.ModuleMatrix.Count;
+
+ foreach (var pattern in typeof(MaskPattern).GetMethods())
+ {
+ if (pattern.Name.Length == 8 && pattern.Name.Substring(0, 7) == "Pattern")
+ {
+ QRCode qrTemp = new QRCode(version);
+ for (int y = 0; y < size; y++)
+ {
+ for (int x = 0; x < size; x++)
+ {
+ qrTemp.ModuleMatrix[y][x] = qrCode.ModuleMatrix[y][x];
+ }
+
+ }
+
+
+ for (int x = 0; x < size; x++)
+ {
+ for (int y = 0; y < size; y++)
+ {
+ if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
+ {
+ qrTemp.ModuleMatrix[y][x] ^= (bool)pattern.Invoke(null, new object[] { x, y });
+ }
+ }
+ }
+
+ var score = MaskPattern.Score(ref qrTemp);
+ if (string.IsNullOrEmpty(patternName) || patternScore > score)
+ {
+ patternName = pattern.Name;
+ patternScore = score;
+ }
+
+ }
+ }
+ var patterMethod = typeof(MaskPattern).GetMethods().Where(x => x.Name == patternName).First();
+ for (int x = 0; x < size; x++)
+ {
+ for (int y = 0; y < size; y++)
+ {
+ if (!IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
+ {
+ qrCode.ModuleMatrix[y][x] ^= (bool)patterMethod.Invoke(null, new object[] { x, y });
+ }
+ }
+ }
+ return Convert.ToInt32(patterMethod.Name.Substring(patterMethod.Name.Length - 1, 1)) - 1;
+ }
+
+
+ public static void PlaceDataWords(ref QRCode qrCode, string data, ref List blockedModules)
+ {
+ var size = qrCode.ModuleMatrix.Count;
+ var up = true;
+ var datawords = new Queue();
+ data.ToList().ForEach(x => datawords.Enqueue(x == '0' ? false : true));
+ for (int x = size - 1; x >= 0; x = x - 2)
+ {
+ if (x == 7 || x == 6)
+ x = 5;
+ for (int yMod = 1; yMod <= size; yMod++)
+ {
+ int y = 0;
+ if (up)
+ {
+ y = size - yMod;
+ if (datawords.Count > 0 && !IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
+ qrCode.ModuleMatrix[y][x] = datawords.Dequeue();
+ if (datawords.Count > 0 && x > 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules))
+ qrCode.ModuleMatrix[y][x - 1] = datawords.Dequeue();
+ }
+ else
+ {
+ y = yMod - 1;
+ if (datawords.Count > 0 && !IsBlocked(new Rectangle(x, y, 1, 1), blockedModules))
+ qrCode.ModuleMatrix[y][x] = datawords.Dequeue();
+ if (datawords.Count > 0 && x > 0 && !IsBlocked(new Rectangle(x - 1, y, 1, 1), blockedModules))
+ qrCode.ModuleMatrix[y][x - 1] = datawords.Dequeue();
+ }
+ }
+ up = !up;
+ }
+ }
+
+ public static void ReserveSeperatorAreas(int size, ref List blockedModules)
+ {
+ blockedModules.AddRange(new Rectangle[]{
+ new Rectangle(7, 0, 1, 8),
+ new Rectangle(0, 7, 7, 1),
+ new Rectangle(0, size-8, 8, 1),
+ new Rectangle(7, size-7, 1, 7),
+ new Rectangle(size-8, 0, 1, 8),
+ new Rectangle(size-7, 7, 7, 1)
+ });
+ }
+
+ public static void ReserveVersionAreas(int size, int version, ref List blockedModules)
+ {
+ blockedModules.AddRange(new Rectangle[]{
+ new Rectangle(8, 0, 1, 6),
+ new Rectangle(8, 7, 1, 1),
+ new Rectangle(0, 8, 6, 1),
+ new Rectangle(7, 8, 2, 1),
+ new Rectangle(size-8, 8, 8, 1),
+ new Rectangle(8, size-7, 1, 7)
+ });
+
+ if (version >= 7)
+ {
+ blockedModules.AddRange(new Rectangle[]{
+ new Rectangle(size-11, 0, 3, 6),
+ new Rectangle(0, size-11, 6, 3)
+ });
+ }
+ }
+ public static void PlaceDarkModule(ref QRCode qrCode, int version, ref List blockedModules)
+ {
+ qrCode.ModuleMatrix[4 * version + 9][8] = true;
+ blockedModules.Add(new Rectangle(8, 4 * version + 9, 1, 1));
+ }
+
+ public static void PlaceFinderPatterns(ref QRCode qrCode, ref List blockedModules)
+ {
+ var size = qrCode.ModuleMatrix.Count;
+ int[] locations = { 0, 0, size - 7, 0, 0, size - 7 };
+
+ for (int i = 0; i < 6; i = i + 2)
+ {
+ for (int x = 0; x < 7; x++)
+ {
+ for (int y = 0; y < 7; y++)
+ {
+ if (!(((x == 1 || x == 5) && y > 0 && y < 6) || (x > 0 && x < 6 && (y == 1 || y == 5))))
+ {
+ qrCode.ModuleMatrix[y + locations[i + 1]][x + locations[i]] = true;
+ }
+ }
+ }
+ blockedModules.Add(new Rectangle(locations[i], locations[i + 1], 7, 7));
+ }
+ }
+
+ public static void PlaceAlignmentPatterns(ref QRCode qrCode, List alignmentPatternLocations, ref List blockedModules)
+ {
+ foreach (var loc in alignmentPatternLocations)
+ {
+ var alignmentPatternRect = new Rectangle(loc.X, loc.Y, 5, 5);
+ var blocked = false;
+ foreach (var blockedRect in blockedModules)
+ {
+ if (Intersects(alignmentPatternRect, blockedRect))
+ {
+ blocked = true;
+ break;
+ }
+ }
+ if (blocked)
+ continue;
+
+ for (int x = 0; x < 5; x++)
+ {
+ for (int y = 0; y < 5; y++)
+ {
+ if (y == 0 || y == 4 || x == 0 || x == 4 || (x == 2 && y == 2))
+ {
+ qrCode.ModuleMatrix[loc.Y + y][loc.X + x] = true;
+ }
+ }
+ }
+ blockedModules.Add(new Rectangle(loc.X, loc.Y, 5, 5));
+ }
+ }
+
+ public static void PlaceTimingPatterns(ref QRCode qrCode, ref List blockedModules)
+ {
+ var size = qrCode.ModuleMatrix.Count;
+ for (int i = 8; i < size - 8; i++)
+ {
+ if (i % 2 == 0)
+ {
+ qrCode.ModuleMatrix[6][i] = true;
+ qrCode.ModuleMatrix[i][6] = true;
+ }
+ }
+ blockedModules.AddRange(new Rectangle[]{
+ new Rectangle(6, 8, 1, size-16),
+ new Rectangle(8, 6, size-16, 1)
+ });
+ }
+
+ private static bool Intersects(Rectangle r1, Rectangle r2)
+ {
+ return r2.X < r1.X + r1.Width && r1.X < r2.X + r2.Width && r2.Y < r1.Y + r1.Height && r1.Y < r2.Y + r2.Height;
+ }
+
+ private static bool IsBlocked(Rectangle r1, List blockedModules)
+ {
+ var isBlocked = false;
+ foreach (var blockedMod in blockedModules)
+ {
+ if (Intersects(blockedMod, r1))
+ isBlocked = true;
+ }
+ return isBlocked;
+ }
+
+ private static class MaskPattern
+ {
+ public static bool Pattern1(int x, int y)
+ {
+ return (x + y) % 2 == 0;
+ }
+
+ public static bool Pattern2(int x, int y)
+ {
+ return y % 2 == 0;
+ }
+
+ public static bool Pattern3(int x, int y)
+ {
+ return x % 3 == 0;
+ }
+
+ public static bool Pattern4(int x, int y)
+ {
+ return (x + y) % 3 == 0;
+ }
+
+ public static bool Pattern5(int x, int y)
+ {
+ return (y / 2 + x / 3) % 2 == 0;
+ }
+
+ public static bool Pattern6(int x, int y)
+ {
+ return ((x * y) % 2) + ((x * y) % 3) == 0;
+ }
+
+ public static bool Pattern7(int x, int y)
+ {
+ return (((x * y) % 2) + ((x * y) % 3)) % 2 == 0;
+ }
+
+ public static bool Pattern8(int x, int y)
+ {
+ return (((x + y) % 2) + ((x * y) % 3)) % 2 == 0;
+ }
+
+ public static int Score(ref QRCode qrCode)
+ {
+ var score = 0;
+ var size = qrCode.ModuleMatrix.Count;
+
+ //Penalty 1
+ for (int y = 0; y < size; y++)
+ {
+ var modInRow = 0;
+ var modInColumn = 0;
+ var lastValRow = qrCode.ModuleMatrix[y][0];
+ var lastValColumn = qrCode.ModuleMatrix[0][y];
+ for (int x = 0; x < size; x++)
+ {
+ if (qrCode.ModuleMatrix[y][x] == lastValRow)
+ modInRow++;
+ else
+ modInRow = 1;
+ if (modInRow == 5)
+ score += 3;
+ else if (modInRow > 5)
+ score++;
+ lastValRow = qrCode.ModuleMatrix[y][x];
+
+
+ if (qrCode.ModuleMatrix[x][y] == lastValColumn)
+ modInColumn++;
+ else
+ modInColumn = 1;
+ if (modInColumn == 5)
+ score += 3;
+ else if (modInColumn > 5)
+ score++;
+ lastValColumn = qrCode.ModuleMatrix[x][y];
+ }
+ }
+
+
+ //Penalty 2
+ for (int y = 0; y < size - 1; y++)
+ {
+ for (int x = 0; x < size - 1; x++)
+ {
+ if (qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y][x + 1] &&
+ qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x] &&
+ qrCode.ModuleMatrix[y][x] == qrCode.ModuleMatrix[y + 1][x + 1])
+ score += 3;
+ }
+ }
+
+ //Penalty 3
+ for (int y = 0; y < size; y++)
+ {
+ for (int x = 0; x < size - 10; x++)
+ {
+ if ((qrCode.ModuleMatrix[y][x] &&
+ !qrCode.ModuleMatrix[y][x + 1] &&
+ qrCode.ModuleMatrix[y][x + 2] &&
+ qrCode.ModuleMatrix[y][x + 3] &&
+ qrCode.ModuleMatrix[y][x + 4] &&
+ !qrCode.ModuleMatrix[y][x + 5] &&
+ qrCode.ModuleMatrix[y][x + 6] &&
+ !qrCode.ModuleMatrix[y][x + 7] &&
+ !qrCode.ModuleMatrix[y][x + 8] &&
+ !qrCode.ModuleMatrix[y][x + 9] &&
+ !qrCode.ModuleMatrix[y][x + 10]) ||
+ (!qrCode.ModuleMatrix[y][x] &&
+ !qrCode.ModuleMatrix[y][x + 1] &&
+ !qrCode.ModuleMatrix[y][x + 2] &&
+ !qrCode.ModuleMatrix[y][x + 3] &&
+ qrCode.ModuleMatrix[y][x + 4] &&
+ !qrCode.ModuleMatrix[y][x + 5] &&
+ qrCode.ModuleMatrix[y][x + 6] &&
+ qrCode.ModuleMatrix[y][x + 7] &&
+ qrCode.ModuleMatrix[y][x + 8] &&
+ !qrCode.ModuleMatrix[y][x + 9] &&
+ qrCode.ModuleMatrix[y][x + 10]))
+ {
+ score += 40;
+ }
+
+ if ((qrCode.ModuleMatrix[x][y] &&
+ !qrCode.ModuleMatrix[x + 1][y] &&
+ qrCode.ModuleMatrix[x + 2][y] &&
+ qrCode.ModuleMatrix[x + 3][y] &&
+ qrCode.ModuleMatrix[x + 4][y] &&
+ !qrCode.ModuleMatrix[x + 5][y] &&
+ qrCode.ModuleMatrix[x + 6][y] &&
+ !qrCode.ModuleMatrix[x + 7][y] &&
+ !qrCode.ModuleMatrix[x + 8][y] &&
+ !qrCode.ModuleMatrix[x + 9][y] &&
+ !qrCode.ModuleMatrix[x + 10][y]) ||
+ (!qrCode.ModuleMatrix[x][x] &&
+ !qrCode.ModuleMatrix[x + 1][y] &&
+ !qrCode.ModuleMatrix[x + 2][y] &&
+ !qrCode.ModuleMatrix[x + 3][y] &&
+ qrCode.ModuleMatrix[x + 4][y] &&
+ !qrCode.ModuleMatrix[x + 5][y] &&
+ qrCode.ModuleMatrix[x + 6][y] &&
+ qrCode.ModuleMatrix[x + 7][y] &&
+ qrCode.ModuleMatrix[x + 8][y] &&
+ !qrCode.ModuleMatrix[x + 9][y] &&
+ qrCode.ModuleMatrix[x + 10][y]))
+ {
+ score += 40;
+ }
+ }
+ }
+
+ //Penalty 4
+ var blackModules = 0;
+ foreach (var row in qrCode.ModuleMatrix)
+ foreach (bool bit in row)
+ if (bit)
+ blackModules++;
+
+ var percent = (blackModules / (qrCode.ModuleMatrix.Count * qrCode.ModuleMatrix.Count)) * 100;
+ if (percent % 5 == 0)
+ score += Math.Min((Math.Abs(percent - 55) / 5), (Math.Abs(percent - 45) / 5)) * 10;
+ else
+ score += Math.Min((Math.Abs((int)Math.Floor((decimal)percent / 5) - 50) / 5), (Math.Abs(((int)Math.Floor((decimal)percent / 5) + 5) - 50) / 5)) * 10;
+
+ return score;
+ }
+ }
+
+ }
+
+ private List CalculateECCWords(string bitString, ECCInfo eccInfo)
+ {
+ var eccWords = eccInfo.ECCPerBlock;
+ var messagePolynom = CalculateMessagePolynom(bitString);
+ var generatorPolynom = CalculateGeneratorPolynom(eccWords);
+
+ for (int i = 0; i < messagePolynom.PolyItems.Count; i++)
+ messagePolynom.PolyItems[i] = new PolynomItem()
+ {
+ Coefficient = messagePolynom.PolyItems[i].Coefficient,
+ Exponent = messagePolynom.PolyItems[i].Exponent + eccWords
+ };
+
+ var genLeadtermFactor = messagePolynom.PolyItems[0].Exponent - generatorPolynom.PolyItems[0].Exponent;
+ for (int i = 0; i < generatorPolynom.PolyItems.Count; i++)
+ generatorPolynom.PolyItems[i] = new PolynomItem()
+ {
+ Coefficient = generatorPolynom.PolyItems[i].Coefficient,
+ Exponent = generatorPolynom.PolyItems[i].Exponent + genLeadtermFactor
+ };
+
+ var leadTermSource = messagePolynom;
+ for (int i = 0; i < messagePolynom.PolyItems.Count; i++)
+ {
+
+ var resPoly = MultiplyGeneratorPolynomByLeadterm(generatorPolynom, ConvertToAlphaNotation(leadTermSource).PolyItems[0], i);
+ resPoly = ConvertToDecNotation(resPoly);
+ resPoly = XORPolynoms(leadTermSource, resPoly);
+ leadTermSource = resPoly;
+ }
+ return leadTermSource.PolyItems.Select(x => DecToBin(x.Coefficient, 8)).ToList();
+ }
+
+ private Polynom ConvertToAlphaNotation(Polynom poly)
+ {
+ Polynom newPoly = new Polynom();
+ for (int i = 0; i < poly.PolyItems.Count; i++)
+ newPoly.PolyItems.Add(new PolynomItem()
+ {
+ Coefficient = (poly.PolyItems[i].Coefficient != 0 ? GetAlphaExpFromIntVal(poly.PolyItems[i].Coefficient) : 0),
+ Exponent = poly.PolyItems[i].Exponent
+ });
+ return newPoly;
+ }
+ private Polynom ConvertToDecNotation(Polynom poly)
+ {
+ Polynom newPoly = new Polynom();
+ for (int i = 0; i < poly.PolyItems.Count; i++)
+ newPoly.PolyItems.Add(new PolynomItem()
+ {
+ Coefficient = GetIntValFromAlphaExp(poly.PolyItems[i].Coefficient),
+ Exponent = poly.PolyItems[i].Exponent
+ });
+ return newPoly;
+ }
+
+ private int GetVersion(string plainText, EncodingMode encMode, ECCLevel eccLevel)
+ {
+ var version = capacityTable.Where(
+ x => x.Details.Where(
+ y => (y.ErrorCorrectionLevel == eccLevel
+ && y.CapacityDict[encMode] >= Convert.ToInt32(plainText.Length)
+ )
+ ).Count() > 0
+ ).Select(x => new
+ {
+ version = x.Version,
+ capacity = x.Details.Where(y => y.ErrorCorrectionLevel == eccLevel)
+ .Single()
+ .CapacityDict[encMode]
+ }).Min(x => x.version);
+ return version;
+ }
+
+ private EncodingMode GetEncodingFromPlaintext(string plainText)
+ {
+ if (plainText.All(c => "0123456789".Contains(c)))
+ return EncodingMode.Numeric;
+ else if (plainText.All(c => alphanumEncTable.Contains(c)))
+ return EncodingMode.Alphanumeric;
+ else
+ return EncodingMode.Byte;
+ }
+ private Polynom CalculateMessagePolynom(string bitString)
+ {
+ Polynom messagePol = new Polynom();
+ for (int i = bitString.Length / 8 - 1; i >= 0; i--)
+ {
+ messagePol.PolyItems.Add(new PolynomItem()
+ {
+ Coefficient = BinToDec(bitString.Substring(0, 8)),
+ Exponent = i
+ });
+ bitString = bitString.Remove(0, 8);
+ }
+ return messagePol;
+ }
+ private Polynom CalculateGeneratorPolynom(int numEccWords)
+ {
+ Polynom generatorPolynom = new Polynom();
+ generatorPolynom.PolyItems.AddRange(new PolynomItem[]{
+ new PolynomItem(){ Coefficient = 0, Exponent = 1},
+ new PolynomItem(){ Coefficient = 0, Exponent = 0}
+ });
+ for (int i = 1; i <= numEccWords - 1; i++)
+ {
+ Polynom multiplierPolynom = new Polynom();
+ multiplierPolynom.PolyItems.AddRange(new PolynomItem[]{
+ new PolynomItem(){ Coefficient = 0, Exponent = 1},
+ new PolynomItem(){ Coefficient = i, Exponent = 0}
+ });
+
+ generatorPolynom = MultiplyAlphaPolynoms(generatorPolynom, multiplierPolynom);
+ }
+
+ return generatorPolynom;
+ }
+
+ private List BinaryStringToBitBlockList(string bitString)
+ {
+ return bitString.ToList().Select((x, i) => new { Index = i, Value = x })
+ .GroupBy(x => x.Index / 8)
+ .Select(x => String.Join("", x.Select(v => v.Value.ToString()).ToArray()))
+ .ToList();
+ }
+
+ private int BinToDec(string binStr)
+ {
+ return Convert.ToInt32(binStr, 2);
+ }
+ private string DecToBin(int decNum)
+ {
+ return Convert.ToString(decNum, 2);
+ }
+ private string DecToBin(int decNum, int padLeftUpTo)
+ {
+ var binStr = DecToBin(decNum);
+ return binStr.PadLeft(padLeftUpTo, '0');
+ }
+
+ private int GetCountIndicatorLength(int version, EncodingMode encMode)
+ {
+ if (version < 10)
+ {
+ if (encMode.Equals(EncodingMode.Numeric))
+ return 10;
+ else if (encMode.Equals(EncodingMode.Alphanumeric))
+ return 9;
+ else
+ return 8;
+ }
+ else if (version < 27)
+ {
+ if (encMode.Equals(EncodingMode.Numeric))
+ return 12;
+ else if (encMode.Equals(EncodingMode.Alphanumeric))
+ return 11;
+ else if (encMode.Equals(EncodingMode.Byte))
+ return 16;
+ else
+ return 10;
+ }
+ else
+ {
+ if (encMode.Equals(EncodingMode.Numeric))
+ return 14;
+ else if (encMode.Equals(EncodingMode.Alphanumeric))
+ return 13;
+ else if (encMode.Equals(EncodingMode.Byte))
+ return 16;
+ else
+ return 12;
+ }
+ }
+
+ private bool IsValidISO(string input)
+ {
+ byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(input);
+ String result = Encoding.GetEncoding("ISO-8859-1").GetString(bytes);
+ return String.Equals(input, result);
+ }
+ private string PlainTextToBinary(string plainText, EncodingMode encMode)
+ {
+ if (encMode.Equals(EncodingMode.Numeric))
+ return PlainTextToBinaryNumeric(plainText);
+ else if (encMode.Equals(EncodingMode.Alphanumeric))
+ return PlainTextToBinaryAlphanumeric(plainText);
+ else if (encMode.Equals(EncodingMode.Byte))
+ return PlainTextToBinaryByte(plainText);
+ else
+ return string.Empty;
+ }
+ private string PlainTextToBinaryNumeric(string plainText)
+ {
+ string codeText = string.Empty;
+ while (plainText.Length >= 3)
+ {
+ var dec = Convert.ToInt32(plainText.Substring(0, 3));
+ codeText += DecToBin(dec, 10);
+ plainText = plainText.Substring(3);
+
+ }
+ if (plainText.Length == 2)
+ {
+ var dec = Convert.ToInt32(plainText.Substring(0, plainText.Length));
+ codeText += DecToBin(dec, 7);
+ }
+ else if (plainText.Length == 1)
+ {
+ var dec = Convert.ToInt32(plainText.Substring(0, plainText.Length));
+ codeText += DecToBin(dec, 4);
+ }
+ return codeText;
+ }
+ private string PlainTextToBinaryAlphanumeric(string plainText)
+ {
+ string codeText = string.Empty;
+ while (plainText.Length >= 2)
+ {
+ var token = plainText.Substring(0, 2);
+ var dec = alphanumEncDict[token[0]] * 45 + alphanumEncDict[token[1]];
+ codeText += DecToBin(dec, 11);
+ plainText = plainText.Substring(2);
+
+ }
+ if (plainText.Length > 0)
+ {
+ codeText += DecToBin(alphanumEncDict[plainText[0]], 6);
+ }
+ return codeText;
+ }
+ private string PlainTextToBinaryByte(string plainText)
+ {
+ byte[] codeBytes = new byte[1];
+ string codeText = string.Empty;
+
+ if (IsValidISO(plainText))
+ codeBytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(plainText);
+ else
+ codeBytes = Encoding.UTF8.GetBytes(plainText);
+ foreach (var b in codeBytes)
+ codeText += DecToBin(b, 8);
+
+ return codeText;
+ }
+
+ private Polynom XORPolynoms(Polynom messagePolynom, Polynom resPolynom)
+ {
+ Polynom resultPolynom = new Polynom();
+ Polynom longPoly, shortPoly;
+ if (messagePolynom.PolyItems.Count >= resPolynom.PolyItems.Count)
+ {
+ longPoly = messagePolynom;
+ shortPoly = resPolynom;
+ }
+ else
+ {
+ longPoly = resPolynom;
+ shortPoly = messagePolynom;
+ }
+
+ for (int i = 0; i < longPoly.PolyItems.Count; i++)
+ {
+ PolynomItem polItemRes = new PolynomItem();
+ polItemRes.Coefficient = longPoly.PolyItems[i].Coefficient ^ (shortPoly.PolyItems.Count > i ? shortPoly.PolyItems[i].Coefficient : 0);
+ polItemRes.Exponent = messagePolynom.PolyItems[0].Exponent - i;
+ resultPolynom.PolyItems.Add(polItemRes);
+ }
+ resultPolynom.PolyItems.RemoveAt(0);
+ return resultPolynom;
+ }
+ private Polynom MultiplyGeneratorPolynomByLeadterm(Polynom genPolynom, PolynomItem leadTerm, int lowerExponentBy)
+ {
+ Polynom resultPolynom = new Polynom();
+ foreach (var polItemBase in genPolynom.PolyItems)
+ {
+ PolynomItem polItemRes = new PolynomItem();
+ polItemRes.Coefficient = (polItemBase.Coefficient + leadTerm.Coefficient) % 255;
+ polItemRes.Exponent = polItemBase.Exponent - lowerExponentBy;
+ resultPolynom.PolyItems.Add(polItemRes);
+ }
+ return resultPolynom;
+ }
+ private Polynom MultiplyAlphaPolynoms(Polynom polynomBase, Polynom polynomMultiplier)
+ {
+ Polynom resultPolynom = new Polynom();
+ foreach (var polItemBase in polynomMultiplier.PolyItems)
+ {
+ foreach (var polItemMulti in polynomBase.PolyItems)
+ {
+ PolynomItem polItemRes = new PolynomItem();
+ polItemRes.Coefficient = ShrinkAlphaExp(polItemBase.Coefficient + polItemMulti.Coefficient);
+ polItemRes.Exponent = (polItemBase.Exponent + polItemMulti.Exponent);
+ resultPolynom.PolyItems.Add(polItemRes);
+ }
+ }
+ var exponentsToGlue = resultPolynom.PolyItems.GroupBy(x => x.Exponent).Where(x => x.Count() > 1).Select(x => x.First().Exponent);
+ List gluedPolynoms = new List();
+ foreach (var exponent in exponentsToGlue)
+ {
+ PolynomItem polynomFixed = new PolynomItem();
+ polynomFixed.Exponent = exponent;
+ int coefficient = 0;
+ foreach (var polynomOld in resultPolynom.PolyItems.Where(x => x.Exponent == exponent))
+ {
+ coefficient ^= GetIntValFromAlphaExp(polynomOld.Coefficient);
+ }
+ polynomFixed.Coefficient = GetAlphaExpFromIntVal(coefficient);
+ gluedPolynoms.Add(polynomFixed);
+ }
+ resultPolynom.PolyItems.RemoveAll(x => exponentsToGlue.Contains(x.Exponent));
+ resultPolynom.PolyItems.AddRange(gluedPolynoms);
+ resultPolynom.PolyItems = resultPolynom.PolyItems.OrderByDescending(x => x.Exponent).ToList();
+ return resultPolynom;
+ }
+
+ private int GetIntValFromAlphaExp(int exp)
+ {
+ return galoisField.Where(alog => alog.ExponentAlpha == exp).Select(alog => alog.IntegerValue).First();
+ }
+ private int GetAlphaExpFromIntVal(int intVal)
+ {
+ return galoisField.Where(alog => alog.IntegerValue == intVal).Select(alog => alog.ExponentAlpha).First();
+ }
+ private int ShrinkAlphaExp(int alphaExp)
+ {
+ return (int)((alphaExp % 256) + Math.Floor((double)(alphaExp / 256)));
+ }
+ private void CreateAlphanumEncDict()
+ {
+ alphanumEncDict = new Dictionary();
+ alphanumEncTable.ToList().Select((x, i) => new { Chr = x, Index = i }).ToList().ForEach(x => alphanumEncDict.Add(x.Chr, x.Index));
+ }
+ private void CreateAlignmentPatternTable()
+ {
+ alignmentPatternTable = new List();
+
+ for (int i = 0; i < (7 * 40); i = i + 7)
+ {
+ List points = new List();
+ for (int x = 0; x < 7; x++)
+ {
+ if (alignmentPatternBaseValues[i + x] != 0)
+ {
+ for (int y = 0; y < 7; y++)
+ {
+ if (alignmentPatternBaseValues[i + y] != 0)
+ {
+ Point p = new Point(alignmentPatternBaseValues[i + x] - 2, alignmentPatternBaseValues[i + y] - 2);
+ if (!points.Contains(p))
+ points.Add(p);
+ }
+ }
+ }
+ }
+
+ alignmentPatternTable.Add(new AlignmentPattern()
+ {
+ Version = (i + 7) / 7,
+ PatternPositions = points
+ }
+ );
+ }
+ }
+ private void CreateCapacityECCTable()
+ {
+ capacityECCTable = new List();
+ for (int i = 0; i < (4 * 6 * 40); i = i + (4 * 6))
+ {
+ capacityECCTable.AddRange(
+ new ECCInfo[]
+ {
+ new ECCInfo()
+ {
+ Version = (i + 24) / 24,
+ ErrorCorrectionLevel = ECCLevel.L,
+ TotalDataCodewords = capacityECCBaseValues[i],
+ ECCPerBlock = capacityECCBaseValues[i+1],
+ BlocksInGroup1 = capacityECCBaseValues[i+2],
+ CodewordsInGroup1 = capacityECCBaseValues[i+3],
+ BlocksInGroup2 = capacityECCBaseValues[i+4],
+ CodewordsInGroup2 = capacityECCBaseValues[i+5]
+ },
+ new ECCInfo()
+ {
+ Version = (i + 24) / 24,
+ ErrorCorrectionLevel = ECCLevel.M,
+ TotalDataCodewords = capacityECCBaseValues[i+6],
+ ECCPerBlock = capacityECCBaseValues[i+7],
+ BlocksInGroup1 = capacityECCBaseValues[i+8],
+ CodewordsInGroup1 = capacityECCBaseValues[i+9],
+ BlocksInGroup2 = capacityECCBaseValues[i+10],
+ CodewordsInGroup2 = capacityECCBaseValues[i+11]
+ },
+ new ECCInfo()
+ {
+ Version = (i + 24) / 24,
+ ErrorCorrectionLevel = ECCLevel.Q,
+ TotalDataCodewords = capacityECCBaseValues[i+12],
+ ECCPerBlock = capacityECCBaseValues[i+13],
+ BlocksInGroup1 = capacityECCBaseValues[i+14],
+ CodewordsInGroup1 = capacityECCBaseValues[i+15],
+ BlocksInGroup2 = capacityECCBaseValues[i+16],
+ CodewordsInGroup2 = capacityECCBaseValues[i+17]
+ },
+ new ECCInfo()
+ {
+ Version = (i + 24) / 24,
+ ErrorCorrectionLevel = ECCLevel.H,
+ TotalDataCodewords = capacityECCBaseValues[i+18],
+ ECCPerBlock= capacityECCBaseValues[i+19],
+ BlocksInGroup1 = capacityECCBaseValues[i+20],
+ CodewordsInGroup1 = capacityECCBaseValues[i+21],
+ BlocksInGroup2 = capacityECCBaseValues[i+22],
+ CodewordsInGroup2 = capacityECCBaseValues[i+23]
+ }
+ });
+ }
+ }
+ private void CreateCapacityTable()
+ {
+ capacityTable = new List();
+ for (int i = 0; i < (16 * 40); i = i + 16)
+ {
+ capacityTable.Add(new VersionInfo()
+ {
+ Version = (i + 16) / 16,
+ Details = new List
+ {
+ new VersionInfoDetails(){
+ ErrorCorrectionLevel = ECCLevel.L,
+ CapacityDict = new Dictionary(){
+ { EncodingMode.Numeric, capacityBaseValues[i] },
+ { EncodingMode.Alphanumeric, capacityBaseValues[i+1] },
+ { EncodingMode.Byte, capacityBaseValues[i+2] },
+ { EncodingMode.Kanji, capacityBaseValues[i+3] },
+ }
+ },
+ new VersionInfoDetails(){
+ ErrorCorrectionLevel = ECCLevel.M,
+ CapacityDict = new Dictionary(){
+ { EncodingMode.Numeric, capacityBaseValues[i+4] },
+ { EncodingMode.Alphanumeric, capacityBaseValues[i+5] },
+ { EncodingMode.Byte, capacityBaseValues[i+6] },
+ { EncodingMode.Kanji, capacityBaseValues[i+7] },
+ }
+ },
+ new VersionInfoDetails(){
+ ErrorCorrectionLevel = ECCLevel.Q,
+ CapacityDict = new Dictionary(){
+ { EncodingMode.Numeric, capacityBaseValues[i+8] },
+ { EncodingMode.Alphanumeric, capacityBaseValues[i+9] },
+ { EncodingMode.Byte, capacityBaseValues[i+10] },
+ { EncodingMode.Kanji, capacityBaseValues[i+11] },
+ }
+ },
+ new VersionInfoDetails(){
+ ErrorCorrectionLevel = ECCLevel.H,
+ CapacityDict = new Dictionary(){
+ { EncodingMode.Numeric, capacityBaseValues[i+12] },
+ { EncodingMode.Alphanumeric, capacityBaseValues[i+13] },
+ { EncodingMode.Byte, capacityBaseValues[i+14] },
+ { EncodingMode.Kanji, capacityBaseValues[i+15] },
+ }
+ }
+ }
+ });
+ }
+ }
+ private void CreateAntilogTable()
+ {
+ galoisField = new List();
+ int gfItem;
+
+ for (int i = 0; i < 256; i++)
+ {
+ gfItem = (int)Math.Pow(2, i);
+
+ if (i > 7)
+ {
+ gfItem = galoisField[i - 1].IntegerValue * 2;
+ }
+ if (gfItem > 255)
+ {
+ gfItem = gfItem ^ 285;
+ }
+ galoisField.Add(new Antilog() { ExponentAlpha = i, IntegerValue = gfItem });
+ }
+ }
+
+ public enum ECCLevel
+ {
+ L,
+ M,
+ Q,
+ H
+ }
+ private enum EncodingMode
+ {
+ Numeric = 1,
+ Alphanumeric = 2,
+ Byte = 4,
+ Kanji = 8,
+ ECI = 7
+ }
+ private struct AlignmentPattern
+ {
+ public int Version;
+ public List PatternPositions;
+ }
+ private struct CodewordBlock
+ {
+ public int GroupNumber;
+ public int BlockNumber;
+ public string BitString;
+ public List CodeWords;
+ public List ECCWords;
+ }
+ private struct ECCInfo
+ {
+ public int Version;
+ public ECCLevel ErrorCorrectionLevel;
+ public int TotalDataCodewords;
+ public int ECCPerBlock;
+ public int BlocksInGroup1;
+ public int CodewordsInGroup1;
+ public int BlocksInGroup2;
+ public int CodewordsInGroup2;
+ }
+ private struct VersionInfo
+ {
+ public int Version;
+ public List Details;
+ }
+ private struct VersionInfoDetails
+ {
+ public ECCLevel ErrorCorrectionLevel;
+ public Dictionary CapacityDict;
+ }
+ private struct Antilog
+ {
+ public int ExponentAlpha;
+ public int IntegerValue;
+ }
+ private struct PolynomItem
+ {
+ public int Coefficient;
+ public int Exponent;
+ }
+
+ private class Polynom
+ {
+ public Polynom()
+ {
+ PolyItems = new List();
+ }
+
+ public List PolyItems { get; set; }
+
+ public override string ToString()
+ {
+ StringBuilder sb = new StringBuilder();
+ PolyItems.ForEach(x => sb.Append("a^" + x.Coefficient + "*x^" + x.Exponent + " + "));
+
+ return sb.ToString().TrimEnd(new char[] { ' ', '+' });
+ }
+ }
+ public class QRCode
+ {
+ public List ModuleMatrix { get; set; }
+ private int version;
+
+ public QRCode(int version)
+ {
+ this.version = version;
+ var size = ModulesPerSideFromVersion(version);
+ ModuleMatrix = new List();
+ for (int i = 0; i < size; i++)
+ ModuleMatrix.Add(new BitArray(size));
+ }
+
+ public Bitmap GetGraphic(int pixelsPerModule)
+ {
+ var size = ModuleMatrix.Count * pixelsPerModule;
+ Bitmap bmp = new Bitmap(size, size);
+ Graphics gfx = Graphics.FromImage(bmp);
+ for (int x = 0; x < size; x = x + pixelsPerModule)
+ {
+ for (int y = 0; y < size; y = y + pixelsPerModule)
+ {
+ var module = ModuleMatrix[(y + pixelsPerModule) / pixelsPerModule - 1][(x + pixelsPerModule) / pixelsPerModule - 1];
+ if (module)
+ gfx.FillRectangle(Brushes.Black, new Rectangle(x, y, pixelsPerModule, pixelsPerModule));
+ else
+ gfx.FillRectangle(Brushes.White, new Rectangle(x, y, pixelsPerModule, pixelsPerModule));
+ }
+ }
+ gfx.Save();
+ return bmp;
+ }
+
+ private int ModulesPerSideFromVersion(int version)
+ {
+ return 21 + (version - 1) * 4;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Misc/QR.resx b/Misc/QR.resx
new file mode 100644
index 000000000..0c5e1db9e
--- /dev/null
+++ b/Misc/QR.resx
@@ -0,0 +1,219 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+
+
+ AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAE
+ AAAAAAAAAAAAAAAAAAAAAAAAIyMjAQAAAAALCwsPJiYmJysrKycqKionKSkpJykpKScpKSknKioqJyoq
+ KicrKysnJycnJw0ODQ8AAAAAJiYmAQAAAABpaWlHq6ur17+/v+6+vr7svr6+7b6+vu2+vr7tvr6+7b6+
+ vu2+vr7tvr6+7L+/v+6rq6vXampqSAAAAAAoKSgXvr++3eLi4v/g4OD94eHh/+Hh4f/i4uL/4uLi/+Li
+ 4v/i4uL/4eHh/+Dh4P/g4OD94uLi/7+/v90sLCwXfn5+PNna2frg4OD/39/f/uHh4f7h4eH+39/f/uDg
+ 4P7g4OD+39/f/uHh4f7h4OH+39/f/t/g3//a2tr6g4ODPoOCgz7X19f64+Pj/+Li4v7k5OT/4+Tj//Ly
+ 8v/19fX/9PT0//T09P/k5OT/5OTk/+Pj4/7j4+P/19jX+4qLikCDhIM+2tra++Xl5f/k5eT+5OTk//Lz
+ 8v+urq7/RUVF/z4+Pv+Zmpn/8fHx/+Xm5f/k5eT+5eXl/9ra2vyLi4tAhYWFPuXm5vvx8vP/7+/w/v//
+ //+sra3/AgIC/15eXv9tbG3/BQUF/4yMjP//////7+/w/vHy8//l5ub8jY2NQC4uLD5LS0f7UFBL/09P
+ Sv5YWVP/FBUS/29wcP///////////5SUlP8PDw//U1NO/1BQS/5PT0r/S0tH/DIyMEAAAAs+AAAM+wAA
+ Dv8AAA/+AwMS/wAAAP+UlJX///////////+3t7n/AAAA/wAAD/8BAQ/+AAAO/wAADPwCAg5ABARSPgoK
+ k/sNDab/DQ2o/hAQvP8CAmj/IiIW/7Kzrv/Cw8D/NDQm/wAATf8QELz/DQ2q/gwMp/8LC5T8Dg5bQAUF
+ Xj4KCpz7DQ2u/w0NsP4NDbX/Dw+//wUFYf8CAhL/AwMP/wMDTf8ODrj/Dg64/w0NsP4MDK7/Cwud/A8P
+ aEEGBmU9DAyl+w4Otf8ODrf+Dw+6/xAQvv8TE8v/EhK+/xAQvP8TE8v/EBDA/w8Puf8PD7f+Dg61/w0N
+ pvsREW9ACAhtQA8PsfsTE77/ExO//xQUwP8UFML/FBTD/xUVyP8WFsn/FRXE/xQUw/8UFMH/ExO//xMT
+ vv8QELL7ERF3QxkZdCgXF771ExPH/xUVyPwVFcn9FhbL/RcXzP0XF8z9FxfM/RcXy/0XF8v9FhbJ/RUV
+ yPwTE8f/Fxe+9RkZdykAAAAAIyOtghsbx/8ZGcj+GRnJ/xoayf8aGsn/GhrK/xoayv8aGsn/GhrJ/xkZ
+ yf8ZGcj+GxvH/yMjrYQAAAAAAADHAQAAAAAzM51FLCyscCoqrGwqKqxtKSmsbSoqrG0qKqxtKSmsbSoq
+ rG0qKqxsLCyscDMznUUAAAAAAAAAAP//AADAAwAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIAB
+ AACAAQAAgAEAAIABAACAAQAAgAEAAP//AAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKysrCR0dHSMWFhY3GBgYORgYGDkYGBg5GBgYORgY
+ GDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5GBgYORgYGDkYGBg5FxcXNx4e
+ HiQuLi4JAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASEhIARYWFis7OzuVkJCQ2ampqeqqqqrsqqqq7Kqq
+ quyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqqquyqqqrsqqqq7Kqq
+ quypqanqkZGR2j09PZcXFxcsUFBQAQAAAAAAAAAAAAAAAAAAAAASEhIuhISEytvb2/7W1tb/19fX/9jY
+ 2P/Y2Nj/2NjY/9jY2P/Y2Nj/2NjY/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/9nZ2f/Y2Nj/2NjY/9jY
+ 2P/Y2Nj/2NjY/9fX1//W1tb/29vb/oeHh8sTExMvAAAAAAAAAAAAAAAAPDw8DGtra6zZ2dn/2dnZ/9ra
+ 2v/b29v/29vb/9vb2//c3Nz/3Nzc/9zc3P/c3Nz/3d3d/93d3f/d3d3/3d3d/93d3f/d3d3/3Nzc/9zc
+ 3P/c3Nz/3Nzc/9vb2//b29v/29vb/9ra2v/Z2dn/2dnZ/21tba5DQ0MNAAAAAAAAAAAiIiIx1NXU9tna
+ 2f/c3Nz/3d3d/93e3f/e3t7/3t7e/9/f3//f39//39/f/9/g3//g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg
+ 4P/g4OD/39/f/9/f3//f39//3t/e/97e3v/d3t3/3d3d/9zc3P/Z2tn/1dXV9icnJzMAAAAAAAAAAFhZ
+ WFzf4N//3Nzc/97e3v/f39//39/f/9/g3//g4OD/4ODg/+Hh4f/h4eH/4eHh/+Li4v/i4uL/4uLi/+Li
+ 4v/i4uL/4uLi/+Hi4f/h4eH/4eHh/+Dg4P/g4OD/3+Df/9/f3//f39//3t7e/9zc3P/f39//XV1dXQAA
+ AAAAAAAAZmZmZdvc2//e3t7/3+Df/+Dg4P/g4eD/4eHh/+Hi4f/i4uL/4uPi/+Pj4//j4+P/5OTk/+Tk
+ 5P/k5OT/5OTk/+Tk5P/k5OT/4+Pj/+Pj4//j4+P/4uLi/+Li4v/h4eH/4eHh/+Dg4P/f4N//3t7e/9vb
+ 2/9wcHBoAAAAAAAAAABoaGhl3d3d/9/f3//h4eH/4eLh/+Li4v/j4+P/4+Pj/+Tk5P/k5OT/5eXl/+Xl
+ 5f/l5uX/5ubm/+bm5v/m5ub/5ubm/+bm5v/l5eX/5eXl/+Tk5P/k5OT/4+Pj/+Pj4//i4uL/4uLi/+Hh
+ 4f/f39//3N3c/3Nzc2kAAAAAAAAAAGhoaGXe3t7/4ODg/+Li4v/j4+P/4+Pj/+Tk5P/l5eX/5eXl/+bm
+ 5v/m5+b/5+fn/+fn5//n6Of/6Ojo/+jo6P/o6Oj/5+fn/+fn5//n5+f/5ubm/+Xl5f/l5eX/5OTk/+Pk
+ 4//j4+P/4uLi/+Dg4P/e3t7/c3NzaQAAAAAAAAAAaGhoZd/g3//i4uL/5OTk/+Tl5P/l5eX/5ebl/+bn
+ 5v/n5+f/5+jn/+jp6P/p6en/7Ozs/8LCwv+Tk5P/ioqK/66urv/o6ej/6enp/+jp6P/o6Oj/5+jn/+bn
+ 5v/m5ub/5ebl/+Tl5P/k5OT/4uLi/9/g3/9zdHNpAAAAAAAAAABoaWhl4eLh/+Pk4//m5ub/5ubm/+fn
+ 5//n6Of/6Ojo/+np6f/p6un/6urq/8bGxv8yMjL/AAAA/wAAAP8AAAD/AAAA/xMTE/+ZmZn/7Ozs/+rq
+ 6v/p6en/6Ojo/+jo6P/n5+f/5ubm/+bm5v/k5OT/4eHh/3R0dGkAAAAAAAAAAGhpaGXj4+P/5eXl/+fn
+ 5//n6Of/6Ojo/+np6f/q6ur/6urq/+vr6//Dw8P/DAwM/wAAAP8AAAD/Gxsb/ygoKP8BAQH/AAAA/wAA
+ AP+FhYX/7O3s/+rr6v/q6ur/6enp/+jo6P/o6Oj/5+fn/+Xl5f/i4+L/dHR0aQAAAAAAAAAAYWFhZeTl
+ 5P/m5+b/6Ono/+np6f/p6un/6uvq/+vr6//s7Oz/7e7t/ycnJ/8AAAD/Ghoa/7S0tP/m5ub/5OTk/9HR
+ 0f9GRkb/AAAA/wICAv/IyMj/7Ozs/+vs6//q6+r/6urq/+nq6f/o6ej/5+fn/+Tk5P9sbGxpAAAAAAAA
+ AAA9Pj1lj4+P/5OTk/+VlZX/lpaW/5eXl/+YmJj/mZmZ/5qamv92dnb/AAAA/wEBAf+/wL//3Nzc/+Tk
+ 5P/l5eX/3d3d/+Li4v8mJib/AAAA/0ZGRv+ampr/mZmZ/5iYmP+Xl5f/lpaW/5WVlf+Tk5P/j4+P/0ZG
+ RmoAAAAAAAAAAAwMDGUAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/Nzc3/+fn
+ 5//q6ur/7O3s/+zt7P/v7+//39/f/4WFhf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/EBAQagAAAAAAAAAAAwMHZQAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP9NTU3/5ufm//Lz8v/z9PP/8/Tz//X19f/l5eX/nZ2d/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8AAAD/AAAA/wAAAP8GBgpqAAAAAAAAAAAAABZlAQEk/wEBJ/8CAin/AgIq/wICKv8CAiv/AgIs/wIC
+ LP8BAR3/AAAA/xwcHP/w8PD/6+zr//r6+v/6+vr/9PT0/+vr6/9lZWX/AAAA/wAAD/8CAi3/AgIs/wIC
+ K/8CAir/AgIq/wICKf8BASf/AQEl/wUFG2oAAAAAAAAAAAICQGUGBpL/Bwec/wgIo/8JCaf/CQmq/wkJ
+ rf8JCa//Cgqz/wkJqP8AAAL/AAAA/4CAgP/y8/L/6+zr/+3t7f/u7u7/xMTE/wcHB/8AAAD/BgZz/woK
+ s/8JCbD/CQmt/wkJqv8JCaj/CAik/wcHnf8HB5P/Dg5MagAAAAAAAAAAAwNHZQgIk/8JCZ3/Cgqj/wsL
+ p/8LC6n/Cwus/wsLr/8MDLL/DAy2/wYGW/8AAAD/AAAA/1JSUv+sraz/tra2/3h4eP8KCgr/AAAA/wIC
+ Iv8MDLb/DAyy/wsLsP8LC63/Cwuq/wsLp/8KCqT/CQmd/wgIk/8PD1VrAAAAAAAAAAAEBE1lCQmY/woK
+ ov8LC6j/DAyr/wwMrf8MDLD/DAyy/w0Ntf8NDbf/Dg67/wUFSv8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
+ AP8CAiH/DQ2q/w0NuP8NDbX/DQ2z/wwMsP8MDK7/DAyr/wsLqP8KCqL/CQmZ/xAQWmsAAAAAAAAAAAQE
+ UGUKCp7/Cwum/wwMrP8NDa//DQ2w/w0Ns/8ODrX/Dg63/w4Ouf8ODrv/Dw/A/wwMiv8FBTj/AAAG/wAA
+ AP8DAyb/CQls/w8Pu/8PD7z/Dg66/w4OuP8ODrX/DQ2z/w0Nsf8NDa//DAys/wsLp/8KCp7/ERFeawAA
+ AAAAAAAABQVTZQsLpP8MDKv/DQ2w/w4Os/8ODrT/Dg62/w8PuP8PD7r/Dw+8/w8Pvf8QEL//EBDA/xER
+ w/8SEsn/ERHJ/xERxf8QEMD/EBC//w8Pvv8PD7z/Dw+6/w8PuP8ODrf/Dg61/w4Os/8NDbH/DAyr/wsL
+ pP8SEmFrAAAAAAAAAAAGBlZlDAyq/w4OsP8PD7X/Dw+3/w8PuP8QELr/EBC7/xAQvf8REb7/ERHA/xER
+ wf8REcL/EhLC/xISw/8SEsP/EhLC/xERwv8REcH/ERHA/xERvv8QEL3/EBC7/xAQuv8QELj/Dw+3/w8P
+ tf8ODrD/DAyq/xMTZWsAAAAAAAAAAAcHWmUODrD/EBC2/xERuv8REbz/ERG9/xISvv8SEr//EhLA/xMT
+ wf8TE8P/ExPD/xMTxP8TE8X/FBTF/xQUxf8UFMX/ExPE/xMTxP8TE8P/ExPC/xISwf8SEr//EhK+/xER
+ vf8REbz/ERG6/xAQtv8ODrD/FBRpawAAAAAAAAAACAhcYxAQtf8SErv/ExO+/xQUwP8UFMD/FBTB/xUV
+ wv8VFcP/FRXE/xUVxf8WFsb/FhbG/xYWx/8WFsf/FhbH/xYWx/8WFsf/FhbG/xYWxf8VFcT/FRXD/xUV
+ wv8UFMH/FBTB/xQUwP8TE77/EhK7/xAQtf8TE2hoAAAAAAAAAAAQEFNUFRXC/xMTv/8UFMP/FRXE/xUV
+ xP8VFcX/FRXG/xYWx/8WFsf/FhbI/xYWyf8XF8n/FxfK/xcXyv8XF8r/FxfK/xcXyf8XF8n/FhbI/xYW
+ yP8WFsf/FhbG/xUVxf8VFcT/FRXE/xQUw/8TE7//FRXB/xAQV1UAAAAAAAAAAA0NPxkjI8byFBTD/xUV
+ x/8WFsj/FxfJ/xcXyf8XF8r/FxfK/xcXy/8YGMz/GBjM/xgYzP8YGM3/GBjN/xgYzf8YGM3/GBjM/xgY
+ zP8YGMz/GBjL/xcXy/8XF8r/FxfJ/xcXyf8WFsj/FRXH/xQUw/8jI8f0Dg5GGwAAAAAAAAAAFhZxAiUl
+ eIUZGcr/FBTI/xUVyv8WFsv/FhbM/xYWzP8WFsz/FhbN/xcXzf8XF83/FxfN/xcXzv8XF87/FxfO/xcX
+ zv8XF87/FxfN/xcXzf8WFs3/FhbM/xYWzP8WFsz/FhbL/xUVyv8UFMj/GBjJ/yYmeogWFnYCAAAAAAAA
+ AAAAAAAAGBh1BzMzk50kJNP+FxfK/xgYzP8YGMz/GBjN/xgYzf8YGM3/GBjN/xgYzf8ZGc7/GRnO/xkZ
+ zv8ZGc7/GRnO/xkZzv8YGM3/GBjN/xgYzf8YGM3/GBjN/xgYzP8YGMz/FxfK/yMj0v4zM5WfFBRkBwAA
+ AAAAAAAAAAAAAAAAAAAAAAAAHBx7Ay0tdkg3N5emMTGpxSwsp8gsLKfILCynyCwsp8gsLKfILCynyCws
+ p8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyCwsp8gsLKfILCynyDExqcU2NpenLi54Shsb
+ ewMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////8AAAD+AAAAfAAAADwAAAA8AAAAPAAAADwAAAA8AA
+ AAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AAAAPAAAADwAAAA8AA
+ AAPAAAADwAAAA8AAAAPAAAAD4AAAB/gAAB//////
+
+
+
\ No newline at end of file
diff --git a/PKHeX.csproj b/PKHeX.csproj
index ec2c4ba44..45195c73d 100644
--- a/PKHeX.csproj
+++ b/PKHeX.csproj
@@ -72,6 +72,12 @@
+
+ Form
+
+
+ QR.cs
+
Form
@@ -215,6 +221,9 @@
SplashScreen.cs
+
+ QR.cs
+
f2-Text.cs
diff --git a/PKX/f1-Main.Designer.cs b/PKX/f1-Main.Designer.cs
index 4fcf6691c..d453c6225 100644
--- a/PKX/f1-Main.Designer.cs
+++ b/PKX/f1-Main.Designer.cs
@@ -331,6 +331,7 @@ public void InitializeComponent()
this.B_OpenSuperTraining = new System.Windows.Forms.Button();
this.L_SAVINDEX = new System.Windows.Forms.Label();
this.dragout = new System.Windows.Forms.PictureBox();
+ this.L_QR = new System.Windows.Forms.Label();
this.tabMain.SuspendLayout();
this.Tab_Main.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.Label_IsShiny)).BeginInit();
@@ -2596,7 +2597,7 @@ public void InitializeComponent()
this.Menu_Open.Name = "Menu_Open";
this.Menu_Open.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.Menu_Open.ShowShortcutKeys = false;
- this.Menu_Open.Size = new System.Drawing.Size(152, 22);
+ this.Menu_Open.Size = new System.Drawing.Size(114, 22);
this.Menu_Open.Text = "&Open...";
this.Menu_Open.Click += new System.EventHandler(this.mainMenuOpen);
//
@@ -2605,7 +2606,7 @@ public void InitializeComponent()
this.Menu_Save.Name = "Menu_Save";
this.Menu_Save.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.Menu_Save.ShowShortcutKeys = false;
- this.Menu_Save.Size = new System.Drawing.Size(152, 22);
+ this.Menu_Save.Size = new System.Drawing.Size(114, 22);
this.Menu_Save.Text = "&Save as...";
this.Menu_Save.Click += new System.EventHandler(this.mainMenuSave);
//
@@ -2614,7 +2615,7 @@ public void InitializeComponent()
this.Menu_Exit.Name = "Menu_Exit";
this.Menu_Exit.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E)));
this.Menu_Exit.ShowShortcutKeys = false;
- this.Menu_Exit.Size = new System.Drawing.Size(152, 22);
+ this.Menu_Exit.Size = new System.Drawing.Size(114, 22);
this.Menu_Exit.Text = "&Exit";
this.Menu_Exit.Click += new System.EventHandler(this.mainMenuExit);
//
@@ -4029,12 +4030,24 @@ public void InitializeComponent()
this.dragout.MouseLeave += new System.EventHandler(this.dragoutLeave);
this.dragout.MouseHover += new System.EventHandler(this.dragoutHover);
//
+ // L_QR
+ //
+ this.L_QR.AutoSize = true;
+ this.L_QR.Location = new System.Drawing.Point(217, 5);
+ this.L_QR.Name = "L_QR";
+ this.L_QR.Size = new System.Drawing.Size(26, 13);
+ this.L_QR.TabIndex = 61;
+ this.L_QR.Text = "QR!";
+ this.L_QR.Visible = false;
+ this.L_QR.Click += new System.EventHandler(this.clickQR);
+ //
// Form1
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(614, 362);
+ this.Controls.Add(this.L_QR);
this.Controls.Add(this.dragout);
this.Controls.Add(this.L_SAVINDEX);
this.Controls.Add(this.GB_SAVtools);
@@ -4461,6 +4474,7 @@ public void InitializeComponent()
public System.Windows.Forms.ComboBox CB_Species;
public System.Windows.Forms.CheckBox CHK_IsEgg;
private System.Windows.Forms.Button B_SaveBoxBin;
+ private System.Windows.Forms.Label L_QR;
}
}
diff --git a/PKX/f1-Main.cs b/PKX/f1-Main.cs
index e539046f3..1724ba0c6 100644
--- a/PKX/f1-Main.cs
+++ b/PKX/f1-Main.cs
@@ -583,7 +583,7 @@ private void openFile(byte[] input, string path, string ext)
}
#endregion
#region Battle Video
- else if (input.Length == 0x2E60 && BitConverter.ToUInt64(input, 0xE18) != 0)
+ else if (input.Length == 0x2E60 && BitConverter.ToUInt64(input, 0xE18) != 0 && BitConverter.ToUInt16(input, 0xE12) == 0)
{
if (Util.Prompt(MessageBoxButtons.YesNo, "Load Batte Video Pokémon data to " + C_BoxSelect.Text + "?", "The first 24 slots will be overwritten.") != DialogResult.Yes) return;
byte[] ekx = new byte[260];
@@ -1552,7 +1552,14 @@ private void setMarkings()
int gameindex = Util.getIndex(CB_GameOrigin);
PB_MarkPentagon.Image = Util.ChangeOpacity(PB_MarkPentagon.InitialImage, (float)(Convert.ToUInt16(gameindex == 24 || gameindex == 25 || gameindex == 26 || gameindex == 27)) * 0.9 + 0.1);
}
- // Clicked Label Shortcuts //
+ // Clicked Label Shortcuts //
+ private void clickQR(object sender, EventArgs e)
+ {
+ if (!verifiedPKX()) return;
+ byte[] pkx = preparepkx(buff);
+ byte[] ekx = PKX.encryptArray(pkx);
+ new QR(ekx).ShowDialog();
+ }
private void clickFriendship(object sender, EventArgs e)
{
if (ModifierKeys == Keys.Control) // prompt to reset
@@ -2246,7 +2253,7 @@ private void validateComboBox(object sender, CancelEventArgs e)
cb.BackColor = defaultControlWhite;
if (init)
- getQuickFiller(dragout);
+ { getQuickFiller(dragout); }
}
private void validateComboBox2(object sender, EventArgs e)
{
@@ -3774,6 +3781,7 @@ private void getQuickFiller(PictureBox pb, byte[] dslotdata = null)
string file;
+ if (pb == dragout) L_QR.Visible = (species != 0);
if (species == 0)
{ pb.Image = (Image)Properties.Resources.ResourceManager.GetObject("_0"); return; }