blob: 9241d852d5102b7c544d0342e257ef3a13805828 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
public class Base64 {
private Base64() {
}
public static String encode(byte[] bytes) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.length; i += 3) {
builder.append(encodeBlock(bytes, i));
}
return builder.toString();
}
private static char[] encodeBlock(byte[] bytes, int offset) {
int j = 0;
int s = bytes.length - offset - 1;
int l = s < 2 ? s : 2;
for (int i = 0; i <= l; i++) {
byte b = bytes[offset + i];
int n = b >= 0 ? ((int)(b)) : b + 256;
j += n << 8 * (2 - i);
}
char[] ac = new char[4];
for (int k = 0; k < 4; k++) {
int l1 = j >>> 6 * (3 - k) & 0x3f;
ac[k] = getChar(l1);
}
if (s < 1) ac[2] = '=';
if (s < 2) ac[3] = '=';
return ac;
}
private static char getChar( int i) {
if (i >= 0 && i <= 25) return (char)(65 + i);
if (i >= 26 && i <= 51) return (char)(97 + (i - 26));
if (i >= 52 && i <= 61) return (char)(48 + (i - 52));
if (i == 62) return '+';
return i != 63 ? '?' : '/';
}
public static byte[] decode(String s) {
if (s.length() == 0) return new byte[0];
int i = 0;
for (int j = s.length() - 1; j > 0 && s.charAt(j) == '='; j--) {
i++;
}
int len = (s.length() * 6) / 8 - i;
byte[] raw = new byte[len];
int l = 0;
for (int i1 = 0; i1 < s.length(); i1 += 4) {
int j1 = (getValue(s.charAt(i1)) << 18) +
(getValue(s.charAt(i1 + 1)) << 12) +
(getValue(s.charAt(i1 + 2)) << 6) +
(getValue(s.charAt(i1 + 3)));
for (int k = 0; k < 3 && l + k < raw.length; k++) {
raw[l + k] = (byte)(j1 >> 8 * (2 - k) & 0xff);
}
l += 3;
}
return raw;
}
private static int getValue(char c) {
if (c >= 'A' && c <= 'Z') return c - 65;
if (c >= 'a' && c <= 'z') return (c - 97) + 26;
if (c >= '0' && c <= '9') return (c - 48) + 52;
if (c == '+') return 62;
if (c == '/') return 63;
return c != '=' ? -1 : 0;
}
}