Last active
February 24, 2021 06:24
-
-
Save EmilHernvall/953733 to your computer and use it in GitHub Desktop.
Simple base64-encoder for java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Base64 | |
{ | |
public static String encode(byte[] data) | |
{ | |
char[] tbl = { | |
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', | |
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', | |
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', | |
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' }; | |
StringBuilder buffer = new StringBuilder(); | |
int pad = 0; | |
for (int i = 0; i < data.length; i += 3) { | |
int b = ((data[i] & 0xFF) << 16) & 0xFFFFFF; | |
if (i + 1 < data.length) { | |
b |= (data[i+1] & 0xFF) << 8; | |
} else { | |
pad++; | |
} | |
if (i + 2 < data.length) { | |
b |= (data[i+2] & 0xFF); | |
} else { | |
pad++; | |
} | |
for (int j = 0; j < 4 - pad; j++) { | |
int c = (b & 0xFC0000) >> 18; | |
buffer.append(tbl[c]); | |
b <<= 6; | |
} | |
} | |
for (int j = 0; j < pad; j++) { | |
buffer.append("="); | |
} | |
return buffer.toString(); | |
} | |
public static byte[] decode(String data) | |
{ | |
int[] tbl = { | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, | |
55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, | |
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, | |
20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, | |
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, | |
48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | |
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; | |
byte[] bytes = data.getBytes(); | |
ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
for (int i = 0; i < bytes.length; ) { | |
int b = 0; | |
if (tbl[bytes[i]] != -1) { | |
b = (tbl[bytes[i]] & 0xFF) << 18; | |
} | |
// skip unknown characters | |
else { | |
i++; | |
continue; | |
} | |
int num = 0; | |
if (i + 1 < bytes.length && tbl[bytes[i+1]] != -1) { | |
b = b | ((tbl[bytes[i+1]] & 0xFF) << 12); | |
num++; | |
} | |
if (i + 2 < bytes.length && tbl[bytes[i+2]] != -1) { | |
b = b | ((tbl[bytes[i+2]] & 0xFF) << 6); | |
num++; | |
} | |
if (i + 3 < bytes.length && tbl[bytes[i+3]] != -1) { | |
b = b | (tbl[bytes[i+3]] & 0xFF); | |
num++; | |
} | |
while (num > 0) { | |
int c = (b & 0xFF0000) >> 16; | |
buffer.write((char)c); | |
b <<= 8; | |
num--; | |
} | |
i += 4; | |
} | |
return buffer.toByteArray(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.ByteArrayOutputStream; | |
import java.util.Random; | |
import java.util.Arrays; | |
import javax.xml.bind.DatatypeConverter; | |
public class Base64Test | |
{ | |
public static void print(byte[] bytes) | |
{ | |
for (byte b : bytes) { | |
System.out.printf("%02X ", b); | |
} | |
System.out.println(); | |
} | |
public static void main(String[] args) | |
{ | |
int steps = 1000000; | |
Random rand = new Random(System.currentTimeMillis()); | |
System.out.println("Encode, decode"); | |
for (int count = 0; count < steps; count++) { | |
int len = rand.nextInt(100)+1; | |
byte[] original = new byte[len]; | |
for (int i = 0; i < len; i++) { | |
original[i] = (byte)rand.nextInt(0xFF); | |
} | |
String encoded = Base64.encode(original); | |
byte[] decoded = Base64.decode(encoded); | |
if (!Arrays.equals(original, decoded)) { | |
print(original); | |
print(decoded); | |
System.out.println(); | |
} | |
} | |
System.out.println("Encode, decode with other"); | |
for (int count = 0; count < steps; count++) { | |
int len = rand.nextInt(100)+1; | |
byte[] original = new byte[len]; | |
for (int i = 0; i < len; i++) { | |
original[i] = (byte)rand.nextInt(0xFF); | |
} | |
String encoded = Base64.encode(original); | |
byte[] decoded = DatatypeConverter.parseBase64Binary(encoded); | |
if (!Arrays.equals(original, decoded)) { | |
print(original); | |
print(decoded); | |
System.out.println(); | |
} | |
} | |
System.out.println("Encode with other, decode"); | |
for (int count = 0; count < steps; count++) { | |
int len = rand.nextInt(100)+1; | |
byte[] original = new byte[len]; | |
for (int i = 0; i < len; i++) { | |
original[i] = (byte)rand.nextInt(0xFF); | |
} | |
String encoded = DatatypeConverter.printBase64Binary(original); | |
byte[] decoded = Base64.decode(encoded); | |
if (!Arrays.equals(original, decoded)) { | |
print(original); | |
print(decoded); | |
System.out.println(); | |
} | |
} | |
System.out.println("Comparison test"); | |
for (int count = 0; count < 100000; count++) { | |
int len = rand.nextInt(100)+1; | |
byte[] original = new byte[len]; | |
for (int i = 0; i < len; i++) { | |
original[i] = (byte)rand.nextInt(0xFF); | |
} | |
String encoded = DatatypeConverter.printBase64Binary(original); | |
String encoded2 = Base64.encode(original); | |
if (!encoded.equals(encoded2)) { | |
System.out.println("mismatch"); | |
System.out.println(encoded); | |
System.out.println(encoded2); | |
System.out.println(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# script to generate the reverse lookup table | |
s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" | |
res = [(ord(c), i) for i,c in enumerate(s)] | |
lookup = dict(res) | |
f = [] | |
for i in xrange(0,255): | |
if lookup.has_key(i): | |
n = str(lookup[i]) | |
if len(n) == 1: | |
n = " " + n | |
f.append(" " + n) | |
else: | |
f.append(" " + str(-1)) | |
print len(f) | |
print ",".join(f) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@kimwooglae
May I ask you a question?
Why should the length of the
tbl
array be256
instead of255
?