/*
* Copyright 2014 individual contributors as indicated by the @author
* tags
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sector67.otp.encoding;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
/**
*
* @author scott.hasse@gmail.com
*
*/
public class SimpleBase16Encoder implements TextEncoder {
protected int majorChunkSize = 20; //the size in bytes of major chunks
protected int minorChunkSize = 1; //the size in bytes of minor chunks
protected String minorChunkSeparator = " ";
protected String majorChunkSeparator = "\n";
/*
* Sets how many bytes in each major chunk
*/
public void setMajorChunkSize(int majorChunkSize) {
this.majorChunkSize = majorChunkSize;
}
public void setMinorChunkSize(int minorChunkSize) {
this.minorChunkSize = minorChunkSize;
}
public void setMinorChunkSeparator(String minorChunkSeparator) {
this.minorChunkSeparator = minorChunkSeparator;
}
public void setMajorChunkSeparator(String majorChunkSeparator) {
this.majorChunkSeparator = majorChunkSeparator;
}
@Override
public String encode(byte[] input) throws EncodingException {
return getChunkedBase16(input);
}
@Override
public byte[] decode(String input) throws EncodingException {
byte[] result = null;
input = cleanInput(input);
try {
result = Hex.decodeHex(input.toCharArray());
} catch (DecoderException e) {
throw new IllegalArgumentException("The provided input is not valid base16.", e);
}
return result;
}
protected String cleanInput(String input) {
input = input.replaceAll("[" + minorChunkSeparator + majorChunkSeparator + "]","");
return input;
}
protected String bytesToBase16(byte[] input) {
char[] hex = Hex.encodeHex(input);
String result = new String(hex);
return result.toUpperCase();
}
/*
*
*/
protected String getChunkedBase16(byte[] data) {
String base16 = bytesToBase16(data);
StringBuffer result = new StringBuffer();
//For each byte in, there are two characters returned
int base16StringMajorChunkSize = majorChunkSize * 2;
int base16StringMinorChunkSize = minorChunkSize * 2;
int ilength = base16.length();
for (int i = 0; i < ilength; i += base16StringMajorChunkSize) {
String line = base16.substring(i, Math.min(ilength, i + base16StringMajorChunkSize));
int jlength = line.length();
for (int j = 0; j < jlength; j += base16StringMinorChunkSize) {
result.append(line.substring(j, Math.min(jlength, j + base16StringMinorChunkSize)));
if (j + base16StringMinorChunkSize < jlength) {
result.append(minorChunkSeparator);
}
}
result.append(majorChunkSeparator);
}
return result.toString();
}
}