You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Version.cs 22 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. * Copyright 2007 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. using System;
  17. using ZXing.Common;
  18. namespace ZXing.QrCode.Internal
  19. {
  20. /// <summary>
  21. /// See ISO 18004:2006 Annex D
  22. /// </summary>
  23. /// <author>Sean Owen</author>
  24. public sealed class Version
  25. {
  26. /// <summary> See ISO 18004:2006 Annex D.
  27. /// Element i represents the raw version bits that specify version i + 7
  28. /// </summary>
  29. private static readonly int[] VERSION_DECODE_INFO = new[]
  30. {
  31. 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
  32. 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
  33. 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
  34. 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
  35. 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
  36. 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
  37. 0x2542E, 0x26A64, 0x27541, 0x28C69
  38. };
  39. private static readonly Version[] VERSIONS = buildVersions();
  40. private readonly int versionNumber;
  41. private readonly int[] alignmentPatternCenters;
  42. private readonly ECBlocks[] ecBlocks;
  43. private readonly int totalCodewords;
  44. private Version(int versionNumber, int[] alignmentPatternCenters, params ECBlocks[] ecBlocks)
  45. {
  46. this.versionNumber = versionNumber;
  47. this.alignmentPatternCenters = alignmentPatternCenters;
  48. this.ecBlocks = ecBlocks;
  49. int total = 0;
  50. int ecCodewords = ecBlocks[0].ECCodewordsPerBlock;
  51. ECB[] ecbArray = ecBlocks[0].getECBlocks();
  52. foreach (var ecBlock in ecbArray)
  53. {
  54. total += ecBlock.Count * (ecBlock.DataCodewords + ecCodewords);
  55. }
  56. this.totalCodewords = total;
  57. }
  58. /// <summary>
  59. /// Gets the version number.
  60. /// </summary>
  61. public int VersionNumber
  62. {
  63. get
  64. {
  65. return versionNumber;
  66. }
  67. }
  68. /// <summary>
  69. /// Gets the alignment pattern centers.
  70. /// </summary>
  71. public int[] AlignmentPatternCenters
  72. {
  73. get
  74. {
  75. return alignmentPatternCenters;
  76. }
  77. }
  78. /// <summary>
  79. /// Gets the total codewords.
  80. /// </summary>
  81. public int TotalCodewords
  82. {
  83. get
  84. {
  85. return totalCodewords;
  86. }
  87. }
  88. /// <summary>
  89. /// Gets the dimension for version.
  90. /// </summary>
  91. public int DimensionForVersion
  92. {
  93. get
  94. {
  95. return 17 + 4 * versionNumber;
  96. }
  97. }
  98. /// <summary>
  99. /// Gets the EC blocks for level.
  100. /// </summary>
  101. /// <param name="ecLevel">The ec level.</param>
  102. /// <returns></returns>
  103. public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel)
  104. {
  105. return ecBlocks[ecLevel.ordinal()];
  106. }
  107. /// <summary> <p>Deduces version information purely from QR Code dimensions.</p>
  108. ///
  109. /// </summary>
  110. /// <param name="dimension">dimension in modules
  111. /// </param>
  112. /// <returns><see cref="Version" /> for a QR Code of that dimension or null</returns>
  113. public static Version getProvisionalVersionForDimension(int dimension)
  114. {
  115. if (dimension % 4 != 1)
  116. {
  117. return null;
  118. }
  119. try
  120. {
  121. return getVersionForNumber((dimension - 17) >> 2);
  122. }
  123. catch (ArgumentException)
  124. {
  125. return null;
  126. }
  127. }
  128. /// <summary>
  129. /// Gets the version for number.
  130. /// </summary>
  131. /// <param name="versionNumber">The version number.</param>
  132. /// <returns></returns>
  133. public static Version getVersionForNumber(int versionNumber)
  134. {
  135. if (versionNumber < 1 || versionNumber > 40)
  136. {
  137. throw new ArgumentException();
  138. }
  139. return VERSIONS[versionNumber - 1];
  140. }
  141. internal static Version decodeVersionInformation(int versionBits)
  142. {
  143. int bestDifference = Int32.MaxValue;
  144. int bestVersion = 0;
  145. for (int i = 0; i < VERSION_DECODE_INFO.Length; i++)
  146. {
  147. int targetVersion = VERSION_DECODE_INFO[i];
  148. // Do the version info bits match exactly? done.
  149. if (targetVersion == versionBits)
  150. {
  151. return getVersionForNumber(i + 7);
  152. }
  153. // Otherwise see if this is the closest to a real version info bit string
  154. // we have seen so far
  155. int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);
  156. if (bitsDifference < bestDifference)
  157. {
  158. bestVersion = i + 7;
  159. bestDifference = bitsDifference;
  160. }
  161. }
  162. // We can tolerate up to 3 bits of error since no two version info codewords will
  163. // differ in less than 8 bits.
  164. if (bestDifference <= 3)
  165. {
  166. return getVersionForNumber(bestVersion);
  167. }
  168. // If we didn't find a close enough match, fail
  169. return null;
  170. }
  171. /// <summary> See ISO 18004:2006 Annex E</summary>
  172. internal BitMatrix buildFunctionPattern()
  173. {
  174. int dimension = DimensionForVersion;
  175. BitMatrix bitMatrix = new BitMatrix(dimension);
  176. // Top left finder pattern + separator + format
  177. bitMatrix.setRegion(0, 0, 9, 9);
  178. // Top right finder pattern + separator + format
  179. bitMatrix.setRegion(dimension - 8, 0, 8, 9);
  180. // Bottom left finder pattern + separator + format
  181. bitMatrix.setRegion(0, dimension - 8, 9, 8);
  182. // Alignment patterns
  183. int max = alignmentPatternCenters.Length;
  184. for (int x = 0; x < max; x++)
  185. {
  186. int i = alignmentPatternCenters[x] - 2;
  187. for (int y = 0; y < max; y++)
  188. {
  189. if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0))
  190. {
  191. // No alignment patterns near the three finder paterns
  192. continue;
  193. }
  194. bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
  195. }
  196. }
  197. // Vertical timing pattern
  198. bitMatrix.setRegion(6, 9, 1, dimension - 17);
  199. // Horizontal timing pattern
  200. bitMatrix.setRegion(9, 6, dimension - 17, 1);
  201. if (versionNumber > 6)
  202. {
  203. // Version info, top right
  204. bitMatrix.setRegion(dimension - 11, 0, 3, 6);
  205. // Version info, bottom left
  206. bitMatrix.setRegion(0, dimension - 11, 6, 3);
  207. }
  208. return bitMatrix;
  209. }
  210. /// <summary> <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
  211. /// use blocks of differing sizes within one version, so, this encapsulates the parameters for
  212. /// each set of blocks. It also holds the number of error-correction codewords per block since it
  213. /// will be the same across all blocks within one version.</p>
  214. /// </summary>
  215. public sealed class ECBlocks
  216. {
  217. private readonly int ecCodewordsPerBlock;
  218. private readonly ECB[] ecBlocks;
  219. internal ECBlocks(int ecCodewordsPerBlock, params ECB[] ecBlocks)
  220. {
  221. this.ecCodewordsPerBlock = ecCodewordsPerBlock;
  222. this.ecBlocks = ecBlocks;
  223. }
  224. /// <summary>
  225. /// Gets the EC codewords per block.
  226. /// </summary>
  227. public int ECCodewordsPerBlock
  228. {
  229. get
  230. {
  231. return ecCodewordsPerBlock;
  232. }
  233. }
  234. /// <summary>
  235. /// Gets the num blocks.
  236. /// </summary>
  237. public int NumBlocks
  238. {
  239. get
  240. {
  241. int total = 0;
  242. foreach (var ecBlock in ecBlocks)
  243. {
  244. total += ecBlock.Count;
  245. }
  246. return total;
  247. }
  248. }
  249. /// <summary>
  250. /// Gets the total EC codewords.
  251. /// </summary>
  252. public int TotalECCodewords
  253. {
  254. get
  255. {
  256. return ecCodewordsPerBlock * NumBlocks;
  257. }
  258. }
  259. /// <summary>
  260. /// Gets the EC blocks.
  261. /// </summary>
  262. /// <returns></returns>
  263. public ECB[] getECBlocks()
  264. {
  265. return ecBlocks;
  266. }
  267. }
  268. /// <summary> <p>Encapsualtes the parameters for one error-correction block in one symbol version.
  269. /// This includes the number of data codewords, and the number of times a block with these
  270. /// parameters is used consecutively in the QR code version's format.</p>
  271. /// </summary>
  272. public sealed class ECB
  273. {
  274. private readonly int count;
  275. private readonly int dataCodewords;
  276. internal ECB(int count, int dataCodewords)
  277. {
  278. this.count = count;
  279. this.dataCodewords = dataCodewords;
  280. }
  281. /// <summary>
  282. /// Gets the count.
  283. /// </summary>
  284. public int Count
  285. {
  286. get
  287. {
  288. return count;
  289. }
  290. }
  291. /// <summary>
  292. /// Gets the data codewords.
  293. /// </summary>
  294. public int DataCodewords
  295. {
  296. get
  297. {
  298. return dataCodewords;
  299. }
  300. }
  301. }
  302. /// <summary>
  303. /// Returns a <see cref="System.String"/> that represents this instance.
  304. /// </summary>
  305. /// <returns>
  306. /// A <see cref="System.String"/> that represents this instance.
  307. /// </returns>
  308. public override String ToString()
  309. {
  310. return Convert.ToString(versionNumber);
  311. }
  312. /// <summary> See ISO 18004:2006 6.5.1 Table 9</summary>
  313. private static Version[] buildVersions()
  314. {
  315. return new Version[]{
  316. new Version(1, new int[]{},
  317. new ECBlocks(7, new ECB(1, 19)),
  318. new ECBlocks(10, new ECB(1, 16)),
  319. new ECBlocks(13, new ECB(1, 13)),
  320. new ECBlocks(17, new ECB(1, 9))),
  321. new Version(2, new int[]{6, 18},
  322. new ECBlocks(10, new ECB(1, 34)),
  323. new ECBlocks(16, new ECB(1, 28)),
  324. new ECBlocks(22, new ECB(1, 22)),
  325. new ECBlocks(28, new ECB(1, 16))),
  326. new Version(3, new int[]{6, 22},
  327. new ECBlocks(15, new ECB(1, 55)),
  328. new ECBlocks(26, new ECB(1, 44)),
  329. new ECBlocks(18, new ECB(2, 17)),
  330. new ECBlocks(22, new ECB(2, 13))),
  331. new Version(4, new int[]{6, 26},
  332. new ECBlocks(20, new ECB(1, 80)),
  333. new ECBlocks(18, new ECB(2, 32)),
  334. new ECBlocks(26, new ECB(2, 24)),
  335. new ECBlocks(16, new ECB(4, 9))),
  336. new Version(5, new int[]{6, 30},
  337. new ECBlocks(26, new ECB(1, 108)),
  338. new ECBlocks(24, new ECB(2, 43)),
  339. new ECBlocks(18, new ECB(2, 15),
  340. new ECB(2, 16)),
  341. new ECBlocks(22, new ECB(2, 11),
  342. new ECB(2, 12))),
  343. new Version(6, new int[]{6, 34},
  344. new ECBlocks(18, new ECB(2, 68)),
  345. new ECBlocks(16, new ECB(4, 27)),
  346. new ECBlocks(24, new ECB(4, 19)),
  347. new ECBlocks(28, new ECB(4, 15))),
  348. new Version(7, new int[]{6, 22, 38},
  349. new ECBlocks(20, new ECB(2, 78)),
  350. new ECBlocks(18, new ECB(4, 31)),
  351. new ECBlocks(18, new ECB(2, 14),
  352. new ECB(4, 15)),
  353. new ECBlocks(26, new ECB(4, 13),
  354. new ECB(1, 14))),
  355. new Version(8, new int[]{6, 24, 42},
  356. new ECBlocks(24, new ECB(2, 97)),
  357. new ECBlocks(22, new ECB(2, 38),
  358. new ECB(2, 39)),
  359. new ECBlocks(22, new ECB(4, 18),
  360. new ECB(2, 19)),
  361. new ECBlocks(26, new ECB(4, 14),
  362. new ECB(2, 15))),
  363. new Version(9, new int[]{6, 26, 46},
  364. new ECBlocks(30, new ECB(2, 116)),
  365. new ECBlocks(22, new ECB(3, 36),
  366. new ECB(2, 37)),
  367. new ECBlocks(20, new ECB(4, 16),
  368. new ECB(4, 17)),
  369. new ECBlocks(24, new ECB(4, 12),
  370. new ECB(4, 13))),
  371. new Version(10, new int[]{6, 28, 50},
  372. new ECBlocks(18, new ECB(2, 68),
  373. new ECB(2, 69)),
  374. new ECBlocks(26, new ECB(4, 43),
  375. new ECB(1, 44)),
  376. new ECBlocks(24, new ECB(6, 19),
  377. new ECB(2, 20)),
  378. new ECBlocks(28, new ECB(6, 15),
  379. new ECB(2, 16))),
  380. new Version(11, new int[]{6, 30, 54}, new ECBlocks(20, new ECB(4, 81)),
  381. new ECBlocks(30, new ECB(1, 50), new ECB(4, 51)), new ECBlocks(28, new ECB(4, 22), new ECB(4, 23)), new ECBlocks(24, new ECB(3, 12), new ECB(8, 13))), new Version(12, new int[]{6, 32, 58}, new ECBlocks(24, new ECB(2, 92), new ECB(2, 93)), new ECBlocks(22, new ECB(6, 36), new ECB(2, 37)), new ECBlocks(26, new ECB(4, 20), new ECB(6, 21)), new ECBlocks(28, new ECB(7, 14), new ECB(4, 15))), new Version(13, new int[]{6, 34, 62}, new ECBlocks(26, new ECB(4, 107)), new ECBlocks(22, new ECB(8, 37), new ECB(1, 38)), new ECBlocks(24, new ECB(8, 20), new ECB(4, 21)), new ECBlocks(22, new ECB(12, 11), new ECB(4, 12))), new Version(14, new int[]{6, 26, 46, 66}, new ECBlocks(30, new ECB(3, 115), new ECB(1, 116)), new ECBlocks(24, new ECB(4, 40), new ECB(5, 41)), new ECBlocks(20, new ECB(11, 16), new ECB(5, 17)), new ECBlocks(24, new ECB(11, 12), new ECB(5, 13))), new Version(15, new int[]{6, 26, 48, 70}, new ECBlocks(22, new ECB(5, 87), new ECB(1, 88)), new ECBlocks(24, new ECB(5, 41), new ECB(5, 42)), new ECBlocks(30, new ECB(5, 24), new ECB(7, 25)), new ECBlocks(24, new ECB(11, 12), new ECB(7, 13))), new Version(16, new int[]{6, 26, 50, 74}, new ECBlocks(24, new ECB(5, 98), new ECB(1, 99)), new ECBlocks(28, new ECB(7, 45), new ECB(3, 46)), new ECBlocks(24, new ECB(15, 19), new ECB(2, 20)), new ECBlocks(30, new ECB(3, 15), new ECB(13, 16))), new Version(17, new int[]{6, 30, 54, 78}, new ECBlocks(28, new ECB(1, 107), new ECB(5, 108)), new ECBlocks(28, new ECB(10, 46), new ECB(1, 47)), new ECBlocks(28, new ECB(1, 22), new ECB(15, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(17, 15))), new Version(18, new int[]{6, 30, 56, 82}, new ECBlocks(30, new ECB(5, 120), new ECB(1, 121)), new ECBlocks(26, new ECB(9, 43), new ECB(4, 44)), new ECBlocks(28, new ECB(17, 22), new ECB(1, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(19, 15))), new Version(19, new int[]{6, 30, 58, 86}, new ECBlocks(28, new ECB(3, 113), new ECB(4, 114)), new ECBlocks(26, new ECB(3, 44), new ECB(11, 45)), new ECBlocks(26, new ECB(17, 21),
  382. new ECB(4, 22)), new ECBlocks(26, new ECB(9, 13), new ECB(16, 14))), new Version(20, new int[]{6, 34, 62, 90}, new ECBlocks(28, new ECB(3, 107), new ECB(5, 108)), new ECBlocks(26, new ECB(3, 41), new ECB(13, 42)), new ECBlocks(30, new ECB(15, 24), new ECB(5, 25)), new ECBlocks(28, new ECB(15, 15), new ECB(10, 16))), new Version(21, new int[]{6, 28, 50, 72, 94}, new ECBlocks(28, new ECB(4, 116), new ECB(4, 117)), new ECBlocks(26, new ECB(17, 42)), new ECBlocks(28, new ECB(17, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(19, 16), new ECB(6, 17))), new Version(22, new int[]{6, 26, 50, 74, 98}, new ECBlocks(28, new ECB(2, 111), new ECB(7, 112)), new ECBlocks(28, new ECB(17, 46)), new ECBlocks(30, new ECB(7, 24), new ECB(16, 25)), new ECBlocks(24, new ECB(34, 13))), new Version(23, new int[]{6, 30, 54, 74, 102}, new ECBlocks(30, new ECB(4, 121), new ECB(5, 122)), new ECBlocks(28, new ECB(4, 47), new ECB(14, 48)), new ECBlocks(30, new ECB(11, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(16, 15), new ECB(14, 16))), new Version(24, new int[]{6, 28, 54, 80, 106}, new ECBlocks(30, new ECB(6, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(6, 45), new ECB(14, 46)), new ECBlocks(30, new ECB(11, 24), new ECB(16, 25)), new ECBlocks(30, new ECB(30, 16), new ECB(2, 17))), new Version(25, new int[]{6, 32, 58, 84, 110}, new ECBlocks(26, new ECB(8, 106), new ECB(4, 107)), new ECBlocks(28, new ECB(8, 47), new ECB(13, 48)), new ECBlocks(30, new ECB(7, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(13, 16))), new Version(26, new int[]{6, 30, 58, 86, 114}, new ECBlocks(28, new ECB(10, 114), new ECB(2, 115)), new ECBlocks(28, new ECB(19, 46), new ECB(4, 47)), new ECBlocks(28, new ECB(28, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(33, 16), new ECB(4, 17))), new Version(27, new int[]{6, 34, 62, 90, 118}, new ECBlocks(30, new ECB(8, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(22, 45), new ECB(3, 46)), new ECBlocks(30, new ECB(8, 23), new ECB(26, 24)), new ECBlocks(30, new ECB(12, 15),
  383. new ECB(28, 16))), new Version(28, new int[]{6, 26, 50, 74, 98, 122}, new ECBlocks(30, new ECB(3, 117), new ECB(10, 118)), new ECBlocks(28, new ECB(3, 45), new ECB(23, 46)), new ECBlocks(30, new ECB(4, 24), new ECB(31, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(31, 16))), new Version(29, new int[]{6, 30, 54, 78, 102, 126}, new ECBlocks(30, new ECB(7, 116), new ECB(7, 117)), new ECBlocks(28, new ECB(21, 45), new ECB(7, 46)), new ECBlocks(30, new ECB(1, 23), new ECB(37, 24)), new ECBlocks(30, new ECB(19, 15), new ECB(26, 16))), new Version(30, new int[]{6, 26, 52, 78, 104, 130}, new ECBlocks(30, new ECB(5, 115), new ECB(10, 116)), new ECBlocks(28, new ECB(19, 47), new ECB(10, 48)), new ECBlocks(30, new ECB(15, 24), new ECB(25, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(25, 16))), new Version(31, new int[]{6, 30, 56, 82, 108, 134}, new ECBlocks(30, new ECB(13, 115), new ECB(3, 116)), new ECBlocks(28, new ECB(2, 46), new ECB(29, 47)), new ECBlocks(30, new ECB(42, 24), new ECB(1, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(28, 16))), new Version(32, new int[]{6, 34, 60, 86, 112, 138}, new ECBlocks(30, new ECB(17, 115)), new ECBlocks(28, new ECB(10, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(10, 24), new ECB(35, 25)), new ECBlocks(30, new ECB(19, 15), new ECB(35, 16))), new Version(33, new int[]{6, 30, 58, 86, 114, 142}, new ECBlocks(30, new ECB(17, 115), new ECB(1, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(21, 47)), new ECBlocks(30, new ECB(29, 24), new ECB(19, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(46, 16))), new Version(34, new int[]{6, 34, 62, 90, 118, 146}, new ECBlocks(30, new ECB(13, 115), new ECB(6, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(44, 24), new ECB(7, 25)), new ECBlocks(30, new ECB(59, 16), new ECB(1, 17))), new Version(35, new int[]{6, 30, 54, 78, 102, 126, 150}, new ECBlocks(30, new ECB(12, 121), new ECB(7, 122)), new ECBlocks(28, new ECB(12, 47), new ECB(26, 48)), new ECBlocks(30, new ECB(39, 24), new
  384. ECB(14, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(41, 16))), new Version(36, new int[]{6, 24, 50, 76, 102, 128, 154}, new ECBlocks(30, new ECB(6, 121), new ECB(14, 122)), new ECBlocks(28, new ECB(6, 47), new ECB(34, 48)), new ECBlocks(30, new ECB(46, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(2, 15), new ECB(64, 16))), new Version(37, new int[]{6, 28, 54, 80, 106, 132, 158}, new ECBlocks(30, new ECB(17, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(29, 46), new ECB(14, 47)), new ECBlocks(30, new ECB(49, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(24, 15), new ECB(46, 16))), new Version(38, new int[]{6, 32, 58, 84, 110, 136, 162}, new ECBlocks(30, new ECB(4, 122), new ECB(18, 123)), new ECBlocks(28, new ECB(13, 46), new ECB(32, 47)), new ECBlocks(30, new ECB(48, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(42, 15), new ECB(32, 16))), new Version(39, new int[]{6, 26, 54, 82, 110, 138, 166}, new ECBlocks(30, new ECB(20, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(40, 47), new ECB(7, 48)), new ECBlocks(30, new ECB(43, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(10, 15), new ECB(67, 16))), new Version(40, new int[]{6, 30, 58, 86, 114, 142, 170}, new ECBlocks(30, new ECB(19, 118), new ECB(6, 119)), new ECBlocks(28, new ECB(18, 47), new ECB(31, 48)), new ECBlocks(30, new ECB(34, 24), new ECB(34, 25)), new ECBlocks(30, new ECB(20, 15), new ECB(61, 16)))};
  385. }
  386. }
  387. }