Skip to content

Instantly share code, notes, and snippets.

@inabajunmr
Last active November 22, 2020 16:37
Show Gist options
  • Save inabajunmr/63e280d712e0260e023b7e2b8db30282 to your computer and use it in GitHub Desktop.
Save inabajunmr/63e280d712e0260e023b7e2b8db30282 to your computer and use it in GitHub Desktop.
Java Base64
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
public class Main {
private final static String base64chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public static void main(String[] args) {
byte[] a = "あああああ".getBytes();
final String e = encode(a);
System.out.println(e);
System.out.println(Base64.getEncoder().encodeToString(a));
System.out.println(new String(decode(e)));
System.out.println(new String(Base64.getDecoder().decode(e)));
}
static int paddingCount(byte[] a) {
if (a.length % 3 == 1) {
return 2;
} else if (a.length % 3 == 2) {
return 1;
}
return 0;
}
static String encode(byte[] value) {
int padding = paddingCount(value);
byte[] b = Arrays.copyOf(value, value.length + padding);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < b.length; i += 3) {
// 3byte(24bit) to 6bit * 4
final int a24 = (b[i] & 0xFF) << 16 | (b[i + 1] & 0xFF) << 8 | (b[i + 2] & 0xFF); // 3byte to 24bit int
final int a1 = a24 >> 18 & 0b111111; // 1st 6bit
final int a2 = a24 >> 12 & 0b111111; // 2nd 6bit
final int a3 = a24 >> 6 & 0b111111; // 3rd 6bit
final int a4 = a24 & 0b111111; // 4th 6bit
sb.append(base64chars.charAt(a1));
sb.append(base64chars.charAt(a2));
if (i + 2 == b.length - 1) {
if (padding <= 1) {
sb.append(base64chars.charAt(a3));
} else {
sb.append('=');
}
if (padding == 0) {
sb.append(base64chars.charAt(a4));
} else {
sb.append('=');
}
} else {
sb.append(base64chars.charAt(a3));
sb.append(base64chars.charAt(a4));
}
}
return sb.toString();
}
private static byte[] decode(String encoded) {
List<Byte> bytes = new ArrayList<>();
// 4chars(6bit) to 24byte(111111222222333333444444)
for (int i = 0; i < encoded.length(); i += 4) {
int i1 = base64chars.indexOf(encoded.charAt(i));
int i2 = base64chars.indexOf(encoded.charAt(i + 1));
int b1 = i1 << 2 | i2 >> 4; // 11111122
bytes.add((byte) b1);
int i3 = 0;
if (encoded.charAt(i + 2) != '=') {
i3 = base64chars.indexOf(encoded.charAt(i + 2));
int b2 = i2 << 4 & 0b11110000 | i3 >> 2; // 22223333
bytes.add((byte) b2);
}
if (encoded.charAt(i + 3) != '=') {
int i4 = base64chars.indexOf(encoded.charAt(i + 3));
int b3 = i3 << 6 & 0b11000000 | i4; // 33444444
bytes.add((byte) b3);
}
}
byte[] result = new byte[bytes.size()];
for (int i = 0; i < bytes.size(); i++) {
result[i] = bytes.get(i);
}
return result;
}
static void print(int b) {
String str = Integer.toBinaryString(b);
System.out.println(String.format("%32s", str).replace(' ', '0'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment