2 * Copyright 2007 ZXing authors
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
17 using ReaderException = com.google.zxing.ReaderException;
\r
18 using BitMatrix = com.google.zxing.common.BitMatrix;
\r
19 namespace com.google.zxing.qrcode.decoder
\r
22 /// <summary> See ISO 18004:2006 Annex D
\r
25 /// <author> Sean Owen
\r
27 /// <author>www.Redivivus.in (suraj.supekar@redivivus.in) - Ported from ZXING Java Source
\r
29 public sealed class Version
\r
31 public int VersionNumber
\r
35 return versionNumber;
\r
39 public int[] AlignmentPatternCenters
\r
43 return alignmentPatternCenters;
\r
47 public int TotalCodewords
\r
51 return totalCodewords;
\r
55 public int DimensionForVersion
\r
59 return 17 + 4 * versionNumber;
\r
64 /// <summary> See ISO 18004:2006 Annex D.
\r
65 /// Element i represents the raw version bits that specify version i + 7
\r
67 //UPGRADE_NOTE: Final was removed from the declaration of 'VERSION_DECODE_INFO'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
68 private static readonly int[] VERSION_DECODE_INFO = new int[]{0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69};
\r
70 //UPGRADE_NOTE: Final was removed from the declaration of 'VERSIONS '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
71 private static readonly Version[] VERSIONS = buildVersions();
\r
73 //UPGRADE_NOTE: Final was removed from the declaration of 'versionNumber '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
74 private int versionNumber;
\r
75 //UPGRADE_NOTE: Final was removed from the declaration of 'alignmentPatternCenters '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
76 private int[] alignmentPatternCenters;
\r
77 //UPGRADE_NOTE: Final was removed from the declaration of 'ecBlocks '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
78 private ECBlocks[] ecBlocks;
\r
79 //UPGRADE_NOTE: Final was removed from the declaration of 'totalCodewords '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
80 private int totalCodewords;
\r
82 private Version(int versionNumber, int[] alignmentPatternCenters, ECBlocks ecBlocks1, ECBlocks ecBlocks2, ECBlocks ecBlocks3, ECBlocks ecBlocks4)
\r
84 this.versionNumber = versionNumber;
\r
85 this.alignmentPatternCenters = alignmentPatternCenters;
\r
86 this.ecBlocks = new ECBlocks[]{ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4};
\r
88 int ecCodewords = ecBlocks1.ECCodewordsPerBlock;
\r
89 ECB[] ecbArray = ecBlocks1.getECBlocks();
\r
90 for (int i = 0; i < ecbArray.Length; i++)
\r
92 ECB ecBlock = ecbArray[i];
\r
93 total += ecBlock.Count * (ecBlock.DataCodewords + ecCodewords);
\r
95 this.totalCodewords = total;
\r
98 public ECBlocks getECBlocksForLevel(ErrorCorrectionLevel ecLevel)
\r
100 return ecBlocks[ecLevel.ordinal()];
\r
103 /// <summary> <p>Deduces version information purely from QR Code dimensions.</p>
\r
106 /// <param name="dimension">dimension in modules
\r
108 /// <returns> {@link Version} for a QR Code of that dimension
\r
110 /// <throws> ReaderException if dimension is not 1 mod 4 </throws>
\r
111 public static Version getProvisionalVersionForDimension(int dimension)
\r
113 if (dimension % 4 != 1)
\r
115 throw ReaderException.Instance;
\r
119 return getVersionForNumber((dimension - 17) >> 2);
\r
121 catch (System.ArgumentException iae)
\r
123 throw ReaderException.Instance;
\r
127 public static Version getVersionForNumber(int versionNumber)
\r
129 if (versionNumber < 1 || versionNumber > 40)
\r
131 throw new System.ArgumentException();
\r
133 return VERSIONS[versionNumber - 1];
\r
136 internal static Version decodeVersionInformation(int versionBits)
\r
138 int bestDifference = System.Int32.MaxValue;
\r
139 int bestVersion = 0;
\r
140 for (int i = 0; i < VERSION_DECODE_INFO.Length; i++)
\r
142 int targetVersion = VERSION_DECODE_INFO[i];
\r
143 // Do the version info bits match exactly? done.
\r
144 if (targetVersion == versionBits)
\r
146 return getVersionForNumber(i + 7);
\r
148 // Otherwise see if this is the closest to a real version info bit string
\r
149 // we have seen so far
\r
150 int bitsDifference = FormatInformation.numBitsDiffering(versionBits, targetVersion);
\r
151 if (bitsDifference < bestDifference)
\r
153 bestVersion = i + 7;
\r
154 bestDifference = bitsDifference;
\r
157 // We can tolerate up to 3 bits of error since no two version info codewords will
\r
158 // differ in less than 4 bits.
\r
159 if (bestDifference <= 3)
\r
161 return getVersionForNumber(bestVersion);
\r
163 // If we didn't find a close enough match, fail
\r
167 /// <summary> See ISO 18004:2006 Annex E</summary>
\r
168 internal BitMatrix buildFunctionPattern()
\r
170 int dimension = DimensionForVersion;
\r
171 BitMatrix bitMatrix = new BitMatrix(dimension);
\r
173 // Top left finder pattern + separator + format
\r
174 bitMatrix.setRegion(0, 0, 9, 9);
\r
175 // Top right finder pattern + separator + format
\r
176 bitMatrix.setRegion(dimension - 8, 0, 8, 9);
\r
177 // Bottom left finder pattern + separator + format
\r
178 bitMatrix.setRegion(0, dimension - 8, 9, 8);
\r
180 // Alignment patterns
\r
181 int max = alignmentPatternCenters.Length;
\r
182 for (int x = 0; x < max; x++)
\r
184 int i = alignmentPatternCenters[x] - 2;
\r
185 for (int y = 0; y < max; y++)
\r
187 if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0))
\r
189 // No alignment patterns near the three finder paterns
\r
192 bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
\r
196 // Vertical timing pattern
\r
197 bitMatrix.setRegion(6, 9, 1, dimension - 17);
\r
198 // Horizontal timing pattern
\r
199 bitMatrix.setRegion(9, 6, dimension - 17, 1);
\r
201 if (versionNumber > 6)
\r
203 // Version info, top right
\r
204 bitMatrix.setRegion(dimension - 11, 0, 3, 6);
\r
205 // Version info, bottom left
\r
206 bitMatrix.setRegion(0, dimension - 11, 6, 3);
\r
212 /// <summary> <p>Encapsulates a set of error-correction blocks in one symbol version. Most versions will
\r
213 /// use blocks of differing sizes within one version, so, this encapsulates the parameters for
\r
214 /// each set of blocks. It also holds the number of error-correction codewords per block since it
\r
215 /// will be the same across all blocks within one version.</p>
\r
217 public sealed class ECBlocks
\r
219 public int ECCodewordsPerBlock
\r
223 return ecCodewordsPerBlock;
\r
227 public int NumBlocks
\r
232 for (int i = 0; i < ecBlocks.Length; i++)
\r
234 total += ecBlocks[i].Count;
\r
240 public int TotalECCodewords
\r
244 return ecCodewordsPerBlock * NumBlocks;
\r
248 //UPGRADE_NOTE: Final was removed from the declaration of 'ecCodewordsPerBlock '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
249 private int ecCodewordsPerBlock;
\r
250 //UPGRADE_NOTE: Final was removed from the declaration of 'ecBlocks '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
251 private ECB[] ecBlocks;
\r
253 internal ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks)
\r
255 this.ecCodewordsPerBlock = ecCodewordsPerBlock;
\r
256 this.ecBlocks = new ECB[]{ecBlocks};
\r
259 internal ECBlocks(int ecCodewordsPerBlock, ECB ecBlocks1, ECB ecBlocks2)
\r
261 this.ecCodewordsPerBlock = ecCodewordsPerBlock;
\r
262 this.ecBlocks = new ECB[]{ecBlocks1, ecBlocks2};
\r
265 public ECB[] getECBlocks()
\r
271 /// <summary> <p>Encapsualtes the parameters for one error-correction block in one symbol version.
\r
272 /// This includes the number of data codewords, and the number of times a block with these
\r
273 /// parameters is used consecutively in the QR code version's format.</p>
\r
275 public sealed class ECB
\r
285 public int DataCodewords
\r
289 return dataCodewords;
\r
293 //UPGRADE_NOTE: Final was removed from the declaration of 'count '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
295 //UPGRADE_NOTE: Final was removed from the declaration of 'dataCodewords '. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
\r
296 private int dataCodewords;
\r
298 internal ECB(int count, int dataCodewords)
\r
300 this.count = count;
\r
301 this.dataCodewords = dataCodewords;
\r
305 public override System.String ToString()
\r
307 return System.Convert.ToString(versionNumber);
\r
310 /// <summary> See ISO 18004:2006 6.5.1 Table 9</summary>
\r
311 private static Version[] buildVersions()
\r
313 return new Version[]{new Version(1, new int[]{}, new ECBlocks(7, new ECB(1, 19)), new ECBlocks(10, new ECB(1, 16)), new ECBlocks(13, new ECB(1, 13)), new ECBlocks(17, new ECB(1, 9))), new Version(2, new int[]{6, 18}, new ECBlocks(10, new ECB(1, 34)), new ECBlocks(16, new ECB(1, 28)), new ECBlocks(22, new ECB(1, 22)), new ECBlocks(28, new ECB(1, 16))), new Version(3, new int[]{6, 22}, new ECBlocks(15, new ECB(1, 55)), new ECBlocks(26, new ECB(1, 44)), new ECBlocks(18, new ECB(2, 17)), new ECBlocks(22, new ECB(2, 13))), new Version(4, new int[]{6, 26}, new ECBlocks(20, new ECB(1, 80)), new ECBlocks(18, new ECB(2, 32)), new ECBlocks(26, new ECB(2, 24)), new ECBlocks(16, new ECB(4, 9))), new Version(5, new int[]{6, 30}, new ECBlocks(26, new ECB(1, 108)), new ECBlocks(24, new ECB(2, 43)), new ECBlocks(18, new ECB(2, 15), new ECB(2, 16)), new ECBlocks(22, new ECB(2, 11), new ECB(2, 12))), new Version(6, new int[]{6, 34}, new ECBlocks(18, new ECB(2, 68)), new ECBlocks(16, new ECB(4, 27)), new ECBlocks(24, new ECB(4, 19)), new ECBlocks(28, new ECB(4, 15))), new Version(7, new int[]{6, 22, 38}, new ECBlocks(20, new ECB(2, 78)), new ECBlocks(18, new ECB(4, 31)), new ECBlocks(18, new ECB(2, 14), new ECB(4, 15)), new ECBlocks(26, new ECB(4, 13), new ECB(1, 14))), new Version(8, new int[]{6, 24, 42}, new ECBlocks(24, new ECB(2, 97)), new ECBlocks(22, new ECB(2, 38), new ECB(2, 39)), new ECBlocks(22, new ECB(4, 18), new ECB(2, 19)), new ECBlocks(26, new ECB(4, 14), new ECB(2, 15))), new Version(9, new int[]{6, 26, 46}, new ECBlocks(30, new ECB(2, 116)), new ECBlocks(22, new ECB(3, 36), new ECB(2, 37)), new ECBlocks(20, new ECB(4, 16), new ECB(4, 17)), new ECBlocks(24, new ECB(4, 12), new ECB(4, 13))), new Version(10, new int[]{6, 28, 50}, new ECBlocks(18, new ECB(2, 68), new ECB(2, 69)), new ECBlocks(26, new ECB(4, 43), new ECB(1, 44)), new ECBlocks(24, new ECB(6, 19), new ECB(2, 20)), new ECBlocks(28, new ECB(6, 15), new ECB(2, 16))), new Version(11, new int[]{6, 30, 54}, new ECBlocks(20, new ECB(4, 81)),
\r
314 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),
\r
315 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),
\r
316 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
\r
317 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)))};
\r