package org.threadly.litesockets.utils;
/*
* Base64.java
*
* Brazil project web application toolkit,
* export version: 2.0
* Copyright (c) 2000-2002 Sun Microsystems, Inc.
*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is included as
* the file "license.terms", and also available at
* http://www.sun.com/
*
* The Original Code is from:
* Brazil project web application toolkit release 2.0.
* The Initial Developer of the Original Code is: cstevens.
* Portions created by cstevens are Copyright (C) Sun Microsystems,
* Inc. All Rights Reserved.
*
* Contributor(s): cstevens, suhler.
*
* Version: 1.9
* Created by cstevens on 00/04/17
* Last modified by suhler on 02/07/24 10:49:48
*/
/**
* Utility to base64 encode and decode a string.
* @author Stephen Uhler
* @version 1.9, 02/07/24
*/
public class Base64 {
private static final String CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
private Base64() {}
/**
* base-64 encode a string.
* @param str The ascii string to encode.
* @return The base64 encoded result.
*/
public static String encode(final String str) {
return encode(str.getBytes());
}
/**
* base-64 encode a byte array.
* @param src The byte array to encode.
* @return The base64 encoded result.
*/
public static String encode(final byte[] src) {
return encode(src, 0, src.length);
}
/**
* base-64 encode a byte array.
* @param src The byte array to encode.
* @param start The starting index.
* @param length The number of bytes.
* @return The base64 encoded result.
*/
public static String encode(final byte[] src, final int start, final int length) {
StringBuilder sb = new StringBuilder();
int x = 0;
int state = 0; // which char in pattern
int old = 0; // previous byte
int max = length + start;
for (int srcIndex = start; srcIndex<max; srcIndex++) {
x = src[srcIndex];
switch (++state) {
case 1:
sb.append(CHARSET.charAt((x>>2) & 0x3f));
break;
case 2:
sb.append(CHARSET.charAt(((old<<4)&0x30) | ((x>>4)&0xf)));
break;
case 3:
sb.append(CHARSET.charAt(((old<<2)&0x3C) | ((x>>6)&0x3)));
sb.append(CHARSET.charAt(x&0x3F));
state = 0;
break;
default:
break;
}
old = x;
}
// now clean up the end bytes
if(state == 1) {
sb.append(CHARSET.charAt((old<<4) & 0x30)).append("==");
} else if(state == 2) {
sb.append(CHARSET.charAt((old<<2) & 0x3c)).append("=");
}
return sb.toString();
}
/**
* A Base64 decoder. This implementation is slow, and
* doesn't handle wrapped lines.
* The output is undefined if there are errors in the input.
* @param s a Base64 encoded string.
* @return The byte array eith the decoded result.
*/
public static byte[] decode(final String s) {
int end = 0; // end state
if (s.endsWith("=")) {
end++;
}
if (s.endsWith("==")) {
end++;
}
int len = (s.length() + 3)/4 * 3 - end;
byte[] result = new byte[len];
int dst = 0;
try {
for(int src = 0; src< s.length(); src++) {
int code = CHARSET.indexOf(s.charAt(src));
if (code == -1) {
break;
}
switch (src%4) {
case 0:
result[dst] = (byte) (code<<2);
break;
case 1:
result[dst++] |= (byte) ((code>>4) & 0x3);
result[dst] = (byte) (code<<4);
break;
case 2:
result[dst++] |= (byte) ((code>>2) & 0xf);
result[dst] = (byte) (code<<6);
break;
case 3:
result[dst++] |= (byte) (code & 0x3f);
break;
default:
break;
}
}
} catch (ArrayIndexOutOfBoundsException e) {}
return result;
}
}