Skip to content

Commit

Permalink
Feat: Add Base45 Decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
f11h authored Jan 17, 2022
2 parents c59d810 + f28b2ab commit e66da9c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
38 changes: 38 additions & 0 deletions src/main/java/eu/europa/ec/dgc/generation/Base45Encoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,42 @@ public static String encodeToString(byte[] bytes) {
}
return result.toString();
}

/**
* Decode base45 string to byte array.
*
* @param encodedString string
* @return bytes
*/
public static byte[] decodeFromString(String encodedString) {
int remainderSize = encodedString.length() % 3;
if (remainderSize == 1) {
throw new IllegalArgumentException("wrong remainder length: " + remainderSize);
}
int wholeChunkCount = encodedString.length() / 3;
byte[] result = new byte[wholeChunkCount * 2 + (remainderSize == 2 ? 1 : 0)];
int resultIndex = 0;
int wholeChunkLength = wholeChunkCount * 3;
for (int i = 0; i < wholeChunkLength; ) {
int c0 = ALPHABET.indexOf(encodedString.charAt(i++));
int c1 = ALPHABET.indexOf(encodedString.charAt(i++));
int c2 = ALPHABET.indexOf(encodedString.charAt(i++));
if (c0 < 0 || c1 < 0 || c2 < 0) {
throw new IllegalArgumentException("unsupported input character near pos: " + i);
}
int val = c0 + 45 * c1 + 45 * 45 * c2;
if (val > 0xFFFF) {
throw new IllegalArgumentException();
}
result[resultIndex++] = (byte) (val / 256);
result[resultIndex++] = (byte) (val % 256);
}

if (remainderSize != 0) {
int c0 = ALPHABET.indexOf(encodedString.charAt(encodedString.length() - 2));
int c1 = ALPHABET.indexOf(encodedString.charAt(encodedString.length() - 1));
result[resultIndex] = (byte) (c0 + 45 * c1);
}
return result;
}
}
17 changes: 16 additions & 1 deletion src/test/java/eu/europa/ec/dgc/generation/Base45EncoderTest.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package eu.europa.ec.dgc.generation;

import java.nio.charset.StandardCharsets;
import java.util.Random;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

Expand All @@ -13,4 +15,17 @@ void encodeTest() {
byte[] bytes = new byte[] { 0, 2, -2, 30, -12, 23, -23, -40};
assertEquals("200T5WR%UEPT",Base45Encoder.encodeToString(bytes));
}
}

@Test
void encodingDecoding() {
for (int i = 16; i<20; i++) {
byte[] in = new byte[i];
Random rnd = new Random();
rnd.nextBytes(in);

String encoded = Base45Encoder.encodeToString(in);
byte[] out = Base45Encoder.decodeFromString(encoded);
assertArrayEquals(in, out);
}
}
}

0 comments on commit e66da9c

Please sign in to comment.