| 1 | package com.jsql.util.bruter; | |
| 2 | ||
| 3 | // This file is currently unlocked (change this line if you lock the file) | |
| 4 | // | |
| 5 | // $Log: MD4.java,v $ | |
| 6 | // Revision 1.2 1998/01/05 03:41:19 iang | |
| 7 | // Added references only. | |
| 8 | // | |
| 9 | // Revision 1.1.1.1 1997/11/03 22:36:56 hopwood | |
| 10 | // + Imported to CVS (tagged as 'start'). | |
| 11 | // | |
| 12 | // Revision 0.1.0.0 1997/07/14 R. Naffah | |
| 13 | // + original version | |
| 14 | // | |
| 15 | // $Endlog$ | |
| 16 | /* | |
| 17 | * Copyright (c) 1997 Systemics Ltd | |
| 18 | * on behalf of the Cryptix Development Team. All rights reserved. | |
| 19 | */ | |
| 20 | ||
| 21 | import java.security.MessageDigest; | |
| 22 | ||
| 23 | /** | |
| 24 | * Implements the MD4 message digest algorithm in Java. | |
| 25 | * <p> | |
| 26 | * <b>References:</b> | |
| 27 | * <ol> | |
| 28 | * <li> Ronald L. Rivest, | |
| 29 | * "<a href="http://www.roxen.com/rfc/rfc1320.html"> | |
| 30 | * The MD4 Message-Digest Algorithm</a>", | |
| 31 | * IETF RFC-1320 (informational). | |
| 32 | * </ol> | |
| 33 | * | |
| 34 | * <p><b>$Revision: 1.2 $</b> | |
| 35 | * @author Raif S. Naffah | |
| 36 | */ | |
| 37 | public class DigestMD4 extends MessageDigest implements Cloneable { | |
| 38 | | |
| 39 | // MD4 specific object variables | |
| 40 | //........................................................................... | |
| 41 | ||
| 42 | /** | |
| 43 | * The size in bytes of the input block to the tranformation algorithm. | |
| 44 | */ | |
| 45 | private static final int BLOCK_LENGTH = 64; //512 / 8 | |
| 46 | ||
| 47 | /** | |
| 48 | * 4 32-bit words (interim result) | |
| 49 | */ | |
| 50 | private int[] context = new int[4]; | |
| 51 | ||
| 52 | /** | |
| 53 | * Number of bytes processed so far mod. 2 power of 64. | |
| 54 | */ | |
| 55 | private long count; | |
| 56 | ||
| 57 | /** | |
| 58 | * 512 bits input buffer = 16 x 32-bit words holds until reaches 512 bits. | |
| 59 | */ | |
| 60 | private byte[] buffer = new byte[DigestMD4.BLOCK_LENGTH]; | |
| 61 | ||
| 62 | /** | |
| 63 | * 512 bits work buffer = 16 x 32-bit words | |
| 64 | */ | |
| 65 | private final int[] X = new int[16]; | |
| 66 | ||
| 67 | ||
| 68 | // Constructors | |
| 69 | //........................................................................... | |
| 70 | ||
| 71 | public DigestMD4() { | |
| 72 | super("MD4"); | |
| 73 |
1
1. <init> : removed call to com/jsql/util/bruter/DigestMD4::engineReset → KILLED |
this.engineReset(); |
| 74 | } | |
| 75 | ||
| 76 | /** | |
| 77 | * This constructor is here to implement cloneability of this class. | |
| 78 | */ | |
| 79 | private DigestMD4(DigestMD4 md) { | |
| 80 | this(); | |
| 81 | this.context = md.context.clone(); | |
| 82 | this.buffer = md.buffer.clone(); | |
| 83 | this.count = md.count; | |
| 84 | } | |
| 85 | ||
| 86 | ||
| 87 | // Cloneable method implementation | |
| 88 | //........................................................................... | |
| 89 | ||
| 90 | /** | |
| 91 | * Returns a copy of this MD object. | |
| 92 | */ | |
| 93 | @Override | |
| 94 | public Object clone() throws CloneNotSupportedException { | |
| 95 | super.clone(); | |
| 96 |
1
1. clone : replaced return value with null for com/jsql/util/bruter/DigestMD4::clone → NO_COVERAGE |
return new DigestMD4(this); |
| 97 | } | |
| 98 | ||
| 99 | ||
| 100 | // JCE methods | |
| 101 | //........................................................................... | |
| 102 | ||
| 103 | /** | |
| 104 | * Resets this object disregarding any temporary data present at the | |
| 105 | * time of the invocation of this call. | |
| 106 | */ | |
| 107 | @Override | |
| 108 | public void engineReset() { | |
| 109 | // initial values of MD4 i.e. A, B, C, D | |
| 110 | // as per rfc-1320; they are low-order byte first | |
| 111 | this.context[0] = 0x67452301; | |
| 112 | this.context[1] = 0xEFCDAB89; | |
| 113 | this.context[2] = 0x98BADCFE; | |
| 114 | this.context[3] = 0x10325476; | |
| 115 | this.count = 0L; | |
| 116 | | |
| 117 |
2
1. engineReset : negated conditional → SURVIVED 2. engineReset : changed conditional boundary → KILLED |
for (int i = 0; i < DigestMD4.BLOCK_LENGTH; i++) { |
| 118 | this.buffer[i] = 0; | |
| 119 | } | |
| 120 | } | |
| 121 | ||
| 122 | /** | |
| 123 | * Continues an MD4 message digest using the input byte. | |
| 124 | */ | |
| 125 | @Override | |
| 126 | public void engineUpdate(byte b) { | |
| 127 | // compute number of bytes still unhashed; i.e. present in buffer | |
| 128 |
1
1. engineUpdate : Replaced long modulus with multiplication → NO_COVERAGE |
int i = (int)(this.count % DigestMD4.BLOCK_LENGTH); |
| 129 |
1
1. engineUpdate : Replaced long addition with subtraction → NO_COVERAGE |
this.count++; // update number of bytes |
| 130 | this.buffer[i] = b; | |
| 131 | | |
| 132 |
1
1. engineUpdate : negated conditional → NO_COVERAGE |
if (i == DigestMD4.BLOCK_LENGTH - 1) { |
| 133 |
1
1. engineUpdate : removed call to com/jsql/util/bruter/DigestMD4::transform → NO_COVERAGE |
this.transform(this.buffer, 0); |
| 134 | } | |
| 135 | } | |
| 136 | ||
| 137 | /** | |
| 138 | * MD4 block update operation. | |
| 139 | * <p> | |
| 140 | * Continues an MD4 message digest operation, by filling the buffer, | |
| 141 | * transform(ing) data in 512-bit message block(s), updating the variables | |
| 142 | * context and count, and leaving (buffering) the remaining bytes in buffer | |
| 143 | * for the next update or finish. | |
| 144 | * | |
| 145 | * @param input input block | |
| 146 | * @param offset start of meaningful bytes in input | |
| 147 | * @param len count of bytes in input block to consider | |
| 148 | */ | |
| 149 | @Override | |
| 150 | public void engineUpdate(byte[] input, int offset, int len) { | |
| 151 | // make sure we don't exceed input's allocated size/length | |
| 152 |
7
1. engineUpdate : Replaced long addition with subtraction → SURVIVED 2. engineUpdate : negated conditional → KILLED 3. engineUpdate : changed conditional boundary → KILLED 4. engineUpdate : negated conditional → KILLED 5. engineUpdate : changed conditional boundary → KILLED 6. engineUpdate : negated conditional → KILLED 7. engineUpdate : changed conditional boundary → KILLED |
if (offset < 0 || len < 0 || (long) offset + len > input.length) { |
| 153 | throw new ArrayIndexOutOfBoundsException(); | |
| 154 | } | |
| 155 | | |
| 156 | // compute number of bytes still unhashed; i.e. present in buffer | |
| 157 |
1
1. engineUpdate : Replaced long modulus with multiplication → KILLED |
int bufferNdx = (int)(this.count % DigestMD4.BLOCK_LENGTH); |
| 158 |
1
1. engineUpdate : Replaced long addition with subtraction → KILLED |
this.count += len; // update number of bytes |
| 159 |
1
1. engineUpdate : Replaced integer subtraction with addition → KILLED |
int partLen = DigestMD4.BLOCK_LENGTH - bufferNdx; |
| 160 | int i = 0; | |
| 161 | | |
| 162 |
2
1. engineUpdate : negated conditional → KILLED 2. engineUpdate : changed conditional boundary → KILLED |
if (len >= partLen) { |
| 163 | | |
| 164 |
1
1. engineUpdate : removed call to java/lang/System::arraycopy → KILLED |
System.arraycopy(input, offset, this.buffer, bufferNdx, partLen); |
| 165 | ||
| 166 |
1
1. engineUpdate : removed call to com/jsql/util/bruter/DigestMD4::transform → KILLED |
this.transform(this.buffer, 0); |
| 167 | ||
| 168 |
4
1. engineUpdate : Replaced integer subtraction with addition → SURVIVED 2. engineUpdate : changed conditional boundary → SURVIVED 3. engineUpdate : Replaced integer addition with subtraction → KILLED 4. engineUpdate : negated conditional → KILLED |
for (i = partLen; i + DigestMD4.BLOCK_LENGTH - 1 < len; i+= DigestMD4.BLOCK_LENGTH) { |
| 169 |
2
1. engineUpdate : Replaced integer addition with subtraction → NO_COVERAGE 2. engineUpdate : removed call to com/jsql/util/bruter/DigestMD4::transform → NO_COVERAGE |
this.transform(input, offset + i); |
| 170 | } | |
| 171 | | |
| 172 | bufferNdx = 0; | |
| 173 | } | |
| 174 | | |
| 175 | // buffer remaining input | |
| 176 |
2
1. engineUpdate : changed conditional boundary → SURVIVED 2. engineUpdate : negated conditional → KILLED |
if (i < len) { |
| 177 |
3
1. engineUpdate : Replaced integer addition with subtraction → SURVIVED 2. engineUpdate : Replaced integer subtraction with addition → SURVIVED 3. engineUpdate : removed call to java/lang/System::arraycopy → KILLED |
System.arraycopy(input, offset + i, this.buffer, bufferNdx, len - i); |
| 178 | } | |
| 179 | } | |
| 180 | ||
| 181 | /** | |
| 182 | * Completes the hash computation by performing final operations such | |
| 183 | * as padding. At the return of this engineDigest, the MD engine is | |
| 184 | * reset. | |
| 185 | * | |
| 186 | * @return the array of bytes for the resulting hash value. | |
| 187 | */ | |
| 188 | @Override | |
| 189 | public byte[] engineDigest() { | |
| 190 | // pad output to 56 mod 64; as RFC1320 puts it: congruent to 448 mod 512 | |
| 191 |
1
1. engineDigest : Replaced long modulus with multiplication → KILLED |
int bufferNdx = (int)(this.count % DigestMD4.BLOCK_LENGTH); |
| 192 |
4
1. engineDigest : changed conditional boundary → SURVIVED 2. engineDigest : Replaced integer subtraction with addition → NO_COVERAGE 3. engineDigest : negated conditional → KILLED 4. engineDigest : Replaced integer subtraction with addition → KILLED |
int padLen = bufferNdx < 56 ? 56 - bufferNdx : 120 - bufferNdx; |
| 193 | ||
| 194 | // padding is alwas binary 1 followed by binary 0s | |
| 195 |
1
1. engineDigest : Replaced integer addition with subtraction → KILLED |
byte[] tail = new byte[padLen + 8]; |
| 196 | tail[0] = (byte) 0x80; | |
| 197 | ||
| 198 | // append length before final transform: | |
| 199 | // save number of bits, casting the long to an array of 8 bytes | |
| 200 | // save low-order byte first. | |
| 201 |
2
1. engineDigest : negated conditional → KILLED 2. engineDigest : changed conditional boundary → KILLED |
for (int i = 0; i < 8; i++) { |
| 202 |
4
1. engineDigest : Replaced Unsigned Shift Right with Shift Left → SURVIVED 2. engineDigest : Replaced integer addition with subtraction → SURVIVED 3. engineDigest : Replaced long multiplication with division → KILLED 4. engineDigest : Replaced integer multiplication with division → KILLED |
tail[padLen + i] = (byte)((this.count * 8) >>> (8 * i)); |
| 203 | } | |
| 204 | | |
| 205 |
1
1. engineDigest : removed call to com/jsql/util/bruter/DigestMD4::engineUpdate → KILLED |
this.engineUpdate(tail, 0, tail.length); |
| 206 | ||
| 207 | byte[] result = new byte[16]; | |
| 208 | | |
| 209 | // cast this MD4's context (array of 4 ints) into an array of 16 bytes. | |
| 210 |
2
1. engineDigest : changed conditional boundary → KILLED 2. engineDigest : negated conditional → KILLED |
for (int i = 0; i < 4; i++) { |
| 211 |
2
1. engineDigest : changed conditional boundary → KILLED 2. engineDigest : negated conditional → KILLED |
for (int j = 0; j < 4; j++) { |
| 212 |
4
1. engineDigest : Replaced Unsigned Shift Right with Shift Left → KILLED 2. engineDigest : Replaced integer addition with subtraction → KILLED 3. engineDigest : Replaced integer multiplication with division → KILLED 4. engineDigest : Replaced integer multiplication with division → KILLED |
result[i * 4 + j] = (byte)(this.context[i] >>> (8 * j)); |
| 213 | } | |
| 214 | } | |
| 215 | | |
| 216 | // reset the engine | |
| 217 |
1
1. engineDigest : removed call to com/jsql/util/bruter/DigestMD4::engineReset → SURVIVED |
this.engineReset(); |
| 218 | | |
| 219 |
1
1. engineDigest : replaced return value with null for com/jsql/util/bruter/DigestMD4::engineDigest → KILLED |
return result; |
| 220 | } | |
| 221 | ||
| 222 | ||
| 223 | // own methods | |
| 224 | //........................................................................... | |
| 225 | ||
| 226 | /** | |
| 227 | * MD4 basic transformation. | |
| 228 | * <p> | |
| 229 | * Transforms context based on 512 bits from input block starting | |
| 230 | * from the offset'th byte. | |
| 231 | * | |
| 232 | * @param block input sub-array. | |
| 233 | * @param offset starting position of sub-array. | |
| 234 | */ | |
| 235 | private void transform(byte[] block, int offset) { | |
| 236 | // encodes 64 bytes from input block into an array of 16 32-bit | |
| 237 | // entities. Use A as a temp var. | |
| 238 |
2
1. transform : negated conditional → KILLED 2. transform : changed conditional boundary → KILLED |
for (int i = 0; i < 16; i++) { |
| 239 |
14
1. transform : Changed increment from 1 to -1 → KILLED 2. transform : Replaced bitwise AND with OR → KILLED 3. transform : Replaced bitwise OR with AND → KILLED 4. transform : Replaced Shift Left with Shift Right → KILLED 5. transform : Replaced Shift Left with Shift Right → KILLED 6. transform : Replaced bitwise OR with AND → KILLED 7. transform : Changed increment from 1 to -1 → KILLED 8. transform : Changed increment from 1 to -1 → KILLED 9. transform : Replaced bitwise AND with OR → KILLED 10. transform : Replaced bitwise AND with OR → KILLED 11. transform : Replaced Shift Left with Shift Right → KILLED 12. transform : Changed increment from 1 to -1 → KILLED 13. transform : Replaced bitwise AND with OR → KILLED 14. transform : Replaced bitwise OR with AND → KILLED |
this.X[i] = |
| 240 | (block[offset++] & 0xFF) | |
| 241 | | (block[offset++] & 0xFF) << 8 | |
| 242 | | (block[offset++] & 0xFF) << 16 | |
| 243 | | (block[offset++] & 0xFF) << 24; | |
| 244 | } | |
| 245 | ||
| 246 | int A = this.context[0]; | |
| 247 | int B = this.context[1]; | |
| 248 | int C = this.context[2]; | |
| 249 | int D = this.context[3]; | |
| 250 | ||
| 251 | A = this.FF(A, B, C, D, this.X[ 0], 3); | |
| 252 | D = this.FF(D, A, B, C, this.X[ 1], 7); | |
| 253 | C = this.FF(C, D, A, B, this.X[ 2], 11); | |
| 254 | B = this.FF(B, C, D, A, this.X[ 3], 19); | |
| 255 | A = this.FF(A, B, C, D, this.X[ 4], 3); | |
| 256 | D = this.FF(D, A, B, C, this.X[ 5], 7); | |
| 257 | C = this.FF(C, D, A, B, this.X[ 6], 11); | |
| 258 | B = this.FF(B, C, D, A, this.X[ 7], 19); | |
| 259 | A = this.FF(A, B, C, D, this.X[ 8], 3); | |
| 260 | D = this.FF(D, A, B, C, this.X[ 9], 7); | |
| 261 | C = this.FF(C, D, A, B, this.X[10], 11); | |
| 262 | B = this.FF(B, C, D, A, this.X[11], 19); | |
| 263 | A = this.FF(A, B, C, D, this.X[12], 3); | |
| 264 | D = this.FF(D, A, B, C, this.X[13], 7); | |
| 265 | C = this.FF(C, D, A, B, this.X[14], 11); | |
| 266 | B = this.FF(B, C, D, A, this.X[15], 19); | |
| 267 | ||
| 268 | A = this.GG(A, B, C, D, this.X[ 0], 3); | |
| 269 | D = this.GG(D, A, B, C, this.X[ 4], 5); | |
| 270 | C = this.GG(C, D, A, B, this.X[ 8], 9); | |
| 271 | B = this.GG(B, C, D, A, this.X[12], 13); | |
| 272 | A = this.GG(A, B, C, D, this.X[ 1], 3); | |
| 273 | D = this.GG(D, A, B, C, this.X[ 5], 5); | |
| 274 | C = this.GG(C, D, A, B, this.X[ 9], 9); | |
| 275 | B = this.GG(B, C, D, A, this.X[13], 13); | |
| 276 | A = this.GG(A, B, C, D, this.X[ 2], 3); | |
| 277 | D = this.GG(D, A, B, C, this.X[ 6], 5); | |
| 278 | C = this.GG(C, D, A, B, this.X[10], 9); | |
| 279 | B = this.GG(B, C, D, A, this.X[14], 13); | |
| 280 | A = this.GG(A, B, C, D, this.X[ 3], 3); | |
| 281 | D = this.GG(D, A, B, C, this.X[ 7], 5); | |
| 282 | C = this.GG(C, D, A, B, this.X[11], 9); | |
| 283 | B = this.GG(B, C, D, A, this.X[15], 13); | |
| 284 | ||
| 285 | A = this.HH(A, B, C, D, this.X[ 0], 3); | |
| 286 | D = this.HH(D, A, B, C, this.X[ 8], 9); | |
| 287 | C = this.HH(C, D, A, B, this.X[ 4], 11); | |
| 288 | B = this.HH(B, C, D, A, this.X[12], 15); | |
| 289 | A = this.HH(A, B, C, D, this.X[ 2], 3); | |
| 290 | D = this.HH(D, A, B, C, this.X[10], 9); | |
| 291 | C = this.HH(C, D, A, B, this.X[ 6], 11); | |
| 292 | B = this.HH(B, C, D, A, this.X[14], 15); | |
| 293 | A = this.HH(A, B, C, D, this.X[ 1], 3); | |
| 294 | D = this.HH(D, A, B, C, this.X[ 9], 9); | |
| 295 | C = this.HH(C, D, A, B, this.X[ 5], 11); | |
| 296 | B = this.HH(B, C, D, A, this.X[13], 15); | |
| 297 | A = this.HH(A, B, C, D, this.X[ 3], 3); | |
| 298 | D = this.HH(D, A, B, C, this.X[11], 9); | |
| 299 | C = this.HH(C, D, A, B, this.X[ 7], 11); | |
| 300 | B = this.HH(B, C, D, A, this.X[15], 15); | |
| 301 | ||
| 302 |
1
1. transform : Replaced integer addition with subtraction → KILLED |
this.context[0] += A; |
| 303 |
1
1. transform : Replaced integer addition with subtraction → KILLED |
this.context[1] += B; |
| 304 |
1
1. transform : Replaced integer addition with subtraction → KILLED |
this.context[2] += C; |
| 305 |
1
1. transform : Replaced integer addition with subtraction → KILLED |
this.context[3] += D; |
| 306 | } | |
| 307 | ||
| 308 | // The basic MD4 atomic functions. | |
| 309 | ||
| 310 | private int FF(int a, int b, int c, int d, int x, int s) { | |
| 311 |
6
1. FF : Replaced bitwise AND with OR → KILLED 2. FF : Replaced integer addition with subtraction → KILLED 3. FF : Replaced integer addition with subtraction → KILLED 4. FF : Replaced bitwise OR with AND → KILLED 5. FF : Replaced bitwise AND with OR → KILLED 6. FF : Replaced XOR with AND → KILLED |
int t = a + ((b & c) | (~b & d)) + x; |
| 312 |
5
1. FF : replaced int return with 0 for com/jsql/util/bruter/DigestMD4::FF → KILLED 2. FF : Replaced Shift Left with Shift Right → KILLED 3. FF : Replaced bitwise OR with AND → KILLED 4. FF : Replaced Unsigned Shift Right with Shift Left → KILLED 5. FF : Replaced integer subtraction with addition → KILLED |
return t << s | t >>> (32 - s); |
| 313 | } | |
| 314 | | |
| 315 | private int GG(int a, int b, int c, int d, int x, int s) { | |
| 316 |
7
1. GG : Replaced integer addition with subtraction → KILLED 2. GG : Replaced bitwise AND with OR → KILLED 3. GG : Replaced bitwise OR with AND → KILLED 4. GG : Replaced integer addition with subtraction → KILLED 5. GG : Replaced integer addition with subtraction → KILLED 6. GG : Replaced bitwise OR with AND → KILLED 7. GG : Replaced bitwise AND with OR → KILLED |
int t = a + ((b & (c | d)) | (c & d)) + x + 0x5A827999; |
| 317 |
5
1. GG : Replaced Shift Left with Shift Right → KILLED 2. GG : Replaced bitwise OR with AND → KILLED 3. GG : Replaced Unsigned Shift Right with Shift Left → KILLED 4. GG : Replaced integer subtraction with addition → KILLED 5. GG : replaced int return with 0 for com/jsql/util/bruter/DigestMD4::GG → KILLED |
return t << s | t >>> (32 - s); |
| 318 | } | |
| 319 | | |
| 320 | private int HH(int a, int b, int c, int d, int x, int s) { | |
| 321 |
5
1. HH : Replaced integer addition with subtraction → KILLED 2. HH : Replaced integer addition with subtraction → KILLED 3. HH : Replaced XOR with AND → KILLED 4. HH : Replaced XOR with AND → KILLED 5. HH : Replaced integer addition with subtraction → KILLED |
int t = a + (b ^ c ^ d) + x + 0x6ED9EBA1; |
| 322 |
5
1. HH : Replaced Shift Left with Shift Right → KILLED 2. HH : Replaced integer subtraction with addition → KILLED 3. HH : Replaced Unsigned Shift Right with Shift Left → KILLED 4. HH : replaced int return with 0 for com/jsql/util/bruter/DigestMD4::HH → KILLED 5. HH : Replaced bitwise OR with AND → KILLED |
return t << s | t >>> (32 - s); |
| 323 | } | |
| 324 | } | |
Mutations | ||
| 73 |
1.1 |
|
| 96 |
1.1 |
|
| 117 |
1.1 2.2 |
|
| 128 |
1.1 |
|
| 129 |
1.1 |
|
| 132 |
1.1 |
|
| 133 |
1.1 |
|
| 152 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 157 |
1.1 |
|
| 158 |
1.1 |
|
| 159 |
1.1 |
|
| 162 |
1.1 2.2 |
|
| 164 |
1.1 |
|
| 166 |
1.1 |
|
| 168 |
1.1 2.2 3.3 4.4 |
|
| 169 |
1.1 2.2 |
|
| 176 |
1.1 2.2 |
|
| 177 |
1.1 2.2 3.3 |
|
| 191 |
1.1 |
|
| 192 |
1.1 2.2 3.3 4.4 |
|
| 195 |
1.1 |
|
| 201 |
1.1 2.2 |
|
| 202 |
1.1 2.2 3.3 4.4 |
|
| 205 |
1.1 |
|
| 210 |
1.1 2.2 |
|
| 211 |
1.1 2.2 |
|
| 212 |
1.1 2.2 3.3 4.4 |
|
| 217 |
1.1 |
|
| 219 |
1.1 |
|
| 238 |
1.1 2.2 |
|
| 239 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9 10.10 11.11 12.12 13.13 14.14 |
|
| 302 |
1.1 |
|
| 303 |
1.1 |
|
| 304 |
1.1 |
|
| 305 |
1.1 |
|
| 311 |
1.1 2.2 3.3 4.4 5.5 6.6 |
|
| 312 |
1.1 2.2 3.3 4.4 5.5 |
|
| 316 |
1.1 2.2 3.3 4.4 5.5 6.6 7.7 |
|
| 317 |
1.1 2.2 3.3 4.4 5.5 |
|
| 321 |
1.1 2.2 3.3 4.4 5.5 |
|
| 322 |
1.1 2.2 3.3 4.4 5.5 |