YBase64 { public static byte[] decode(byte[] inBytes) { if (null == inBytes) { throw new NullPointerException("Null input buffer"); } int len = inBytes.length; if (len % 4 != 0 && inBytes[len - 1] == '\0') { len -= 1; } if (len % 4 != 0) { throw new CryptoException("String not padded ie, input string not modulo 4 len = " + len + " len%4= " + len % 4); } byte[] out = new byte[y64decodeLen(len)]; int i = 0; int j = 0; int tlen; while (i < len) { tlen = (len - i); if (tlen > 4) { tlen = 4; } if (inBytes[i + 3] == '-') { tlen--; } if (inBytes[i + 2] == '-') { tlen--; } if (inBytes[i + 1] == '-') { throw new CryptoException("Too Many pad characters ( this should never happen )"); } byte a = decodeByte(inBytes[i++]); byte b = decodeByte(inBytes[i++]); byte c = decodeByte(inBytes[i++]); byte d = decodeByte(inBytes[i++]); if (a == (byte) 0xee || b == (byte) 0xee || c == (byte) 0xee || d == (byte) 0xee) { throw new CryptoException("Unrecognized characters in y64-encoded input starting at: " + (i - 4)); } if (tlen == 4) { out[j++] = decode1(a, b); out[j++] = decode2(b, c); out[j++] = decode3(c, d); } else if (tlen == 3) { if ((c & (byte) 0x03) != 0) { throw new CryptoException("Unknown decode error c & 0x03 failed, c-pos: " + (i - 2)); } out[j++] = decode1(a, b); out[j++] = decode2(b, c); } else { if ((b & (byte) 0x0F) != 0) { throw new CryptoException("Invalid decode. b & 0x0f failed, b-pos: " + (i - 3)); } out[j++] = decode1(a, b); } } return Arrays.copyOf(out, j); }  static byte[] decode(byte[] inBytes); static byte[] encode(byte[] inBytes); static final byte[] Y64_DECODE_ARRAY; }
@Test public void testDecodeSinglePaddingCharacter() { byte[] data = YBase64.decode(SINGLE_PADDING.getBytes(StandardCharsets.UTF_8)); assertEquals(new String(data, StandardCharsets.UTF_8), SINGLE_PAD_PUBLIC_KEY); }
@Test public void testDecodeDoublePaddingCharacter() { byte[] data = YBase64.decode(DOUBLE_PADDING.getBytes(StandardCharsets.UTF_8)); assertEquals(new String(data, StandardCharsets.UTF_8), DOUBLE_PAD_PUBLIC_KEY); }
@Test public void testDecodeNoPaddingCharacter() { byte[] data = YBase64.decode(NO_PADDING.getBytes(StandardCharsets.UTF_8)); assertEquals(new String(data, StandardCharsets.UTF_8), NO_PAD_PUBLIC_KEY); }
@Test public void testDecodeInvalidData() { try { YBase64.decode(null); fail(); } catch (NullPointerException ignored) { } try { YBase64.decode("abcde\0".getBytes()); fail(); } catch (CryptoException ignored) { } try { YBase64.decode("a-aa".getBytes()); fail(); } catch (CryptoException ignored) { } try { byte[] a = new byte[] {(byte)0xff,(byte)0x97,(byte)0x97,(byte)0x97}; YBase64.decode(a); fail(); } catch (CryptoException ignored) { } try { byte[] b = new byte[] {(byte)0x97,(byte)0xff,(byte)0x97,(byte)0x97}; YBase64.decode(b); fail(); } catch (CryptoException ignored) { } try { byte[] c = new byte[] {(byte)0x97,(byte)0x97,(byte)0xff,(byte)0x97}; YBase64.decode(c); fail(); } catch (CryptoException ignored) { } try { byte[] d = new byte[] {(byte)0x97,(byte)0x97,(byte)0x97,(byte)0xff}; YBase64.decode(d); fail(); } catch (CryptoException ignored) { } try { YBase64.decode("aaa-".getBytes()); fail(); } catch (CryptoException ignored) { } try { YBase64.decode("aa--".getBytes()); fail(); } catch (CryptoException ignored) { } }