forked from lokeshgupta1981/Core-Java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBase64.java
More file actions
157 lines (134 loc) · 4.56 KB
/
Base64.java
File metadata and controls
157 lines (134 loc) · 4.56 KB
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Copyright (C) 2011 - Will Glozer. All rights reserved.
package com.lambdaworks.codec;
import java.util.Arrays;
/**
* High-performance base64 codec based on the algorithm used in Mikael Grev's MiG Base64.
* This implementation is designed to handle base64 without line splitting and with
* optional padding. Alternative character tables may be supplied to the {@code encode}
* and {@code decode} methods to implement modified base64 schemes.
*
* Decoding assumes correct input, the caller is responsible for ensuring that the input
* contains no invalid characters.
*
* @author Will Glozer
*/
public class Base64 {
private static final char[] encode = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
private static final int[] decode = new int[128];
private static final char pad = '=';
static {
Arrays.fill(decode, -1);
for (int i = 0; i < encode.length; i++) {
decode[encode[i]] = i;
}
decode[pad] = 0;
}
/**
* Decode base64 chars to bytes.
*
* @param chars Chars to encode.
*
* @return Decoded bytes.
*/
public static byte[] decode(char[] chars) {
return decode(chars, decode, pad);
}
/**
* Encode bytes to base64 chars, with padding.
*
* @param bytes Bytes to encode.
*
* @return Encoded chars.
*/
public static char[] encode(byte[] bytes) {
return encode(bytes, encode, pad);
}
/**
* Encode bytes to base64 chars, with optional padding.
*
* @param bytes Bytes to encode.
* @param padded Add padding to output.
*
* @return Encoded chars.
*/
public static char[] encode(byte[] bytes, boolean padded) {
return encode(bytes, encode, padded ? pad : 0);
}
/**
* Decode base64 chars to bytes using the supplied decode table and padding
* character.
*
* @param src Base64 encoded data.
* @param table Decode table.
* @param pad Padding character.
*
* @return Decoded bytes.
*/
public static byte[] decode(char[] src, int[] table, char pad) {
int len = src.length;
if (len == 0) return new byte[0];
int padCount = (src[len - 1] == pad ? (src[len - 2] == pad ? 2 : 1) : 0);
int bytes = (len * 6 >> 3) - padCount;
int blocks = (bytes / 3) * 3;
byte[] dst = new byte[bytes];
int si = 0, di = 0;
while (di < blocks) {
int n = table[src[si++]] << 18 | table[src[si++]] << 12 | table[src[si++]] << 6 | table[src[si++]];
dst[di++] = (byte) (n >> 16);
dst[di++] = (byte) (n >> 8);
dst[di++] = (byte) n;
}
if (di < bytes) {
int n = 0;
switch (len - si) {
case 4: n |= table[src[si+3]];
case 3: n |= table[src[si+2]] << 6;
case 2: n |= table[src[si+1]] << 12;
case 1: n |= table[src[si]] << 18;
}
for (int r = 16; di < bytes; r -= 8) {
dst[di++] = (byte) (n >> r);
}
}
return dst;
}
/**
* Encode bytes to base64 chars using the supplied encode table and with
* optional padding.
*
* @param src Bytes to encode.
* @param table Encoding table.
* @param pad Padding character, or 0 for no padding.
*
* @return Encoded chars.
*/
public static char[] encode(byte[] src, char[] table, char pad) {
int len = src.length;
if (len == 0) return new char[0];
int blocks = (len / 3) * 3;
int chars = ((len - 1) / 3 + 1) << 2;
int tail = len - blocks;
if (pad == 0 && tail > 0) chars -= 3 - tail;
char[] dst = new char[chars];
int si = 0, di = 0;
while (si < blocks) {
int n = (src[si++] & 0xff) << 16 | (src[si++] & 0xff) << 8 | (src[si++] & 0xff);
dst[di++] = table[(n >>> 18) & 0x3f];
dst[di++] = table[(n >>> 12) & 0x3f];
dst[di++] = table[(n >>> 6) & 0x3f];
dst[di++] = table[n & 0x3f];
}
if (tail > 0) {
int n = (src[si] & 0xff) << 10;
if (tail == 2) n |= (src[++si] & 0xff) << 2;
dst[di++] = table[(n >>> 12) & 0x3f];
dst[di++] = table[(n >>> 6) & 0x3f];
if (tail == 2) dst[di++] = table[n & 0x3f];
if (pad != 0) {
if (tail == 1) dst[di++] = pad;
dst[di] = pad;
}
}
return dst;
}
}