// Copyright 2013 Google Inc. All Rights Reserved.
//
// 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.google.enterprise.connector.util;
import com.google.common.base.Charsets;
/**
* Base16 encoder class. Converts strings and byte arrays to hex strings.
* Base16 is an URL-safe and usually order-preserving encoding, but it
* does take more space than some other encodings without those
* properties, such as Base64.
* <p>
* Note: The conversion of Java strings to bytes using UTF-8 is not
* order-preserving, because the binary order of UTF-16 is different
* from UTF-8 in the case of supplementary characters.
*
* @since 3.2.4
* @see <a href="http://tools.ietf.org/html/rfc4648">RFC 4648</a>
* @see <a href="http://www.unicode.org/L2/L2001/01230-utf8s.htm">UTF8-S</a>
*/
/* TODO(jlacey): Replace with Guava's BaseEncoding when we upgrade to r14? */
public class Base16 {
private static final String HEX_STRING = "0123456789abcdef";
private static final char[] HEX_CHARS_LOWER = HEX_STRING.toCharArray();
private static final char[] HEX_CHARS_UPPER =
HEX_STRING.toUpperCase().toCharArray();
/** Constructs a Base16 encoder that uses lowercase hex letters (a-f). */
public static Base16 lowerCase() {
return new Base16(HEX_CHARS_LOWER);
}
/** Constructs a Base16 encoder that uses uppercase hex letters (A-F). */
public static Base16 upperCase() {
return new Base16(HEX_CHARS_UPPER);
}
private final char[] alphabet;
private Base16(char[] alphabet) {
this.alphabet = alphabet;
}
/**
* Encodes a string into Base16 notation. This method does not
* preserve the sort order of the input strings in the presence of
* Unicode supplementary characters.
*
* @param value the data to convert
* @return a string of the equivalent hex representation of the bytes
*/
public String encode(String value) {
return encode(value.getBytes(Charsets.UTF_8));
}
/**
* Encodes a byte array into Base16 notation.
*
* @param value the data to convert
* @return a string of the equivalent hex representation of the bytes
*/
public String encode(byte[] value) {
StringBuilder builder = new StringBuilder(value.length * 2);
encode(value, builder);
return builder.toString();
}
/**
* Encodes a byte array into Base16 notation and appends the result
* to the {@code StringBuilder}.
*
* @param value the data to convert
* @param builder the {@code StringBuilder} to append the encoded string to
*/
public void encode(byte[] value, StringBuilder builder) {
for (byte b : value) {
encode(b, builder);
}
}
/**
* Encodes a single byte into Base16 notation and appends the result
* to the {@code StringBuilder}.
*
* @param b the byte to convert
* @param builder the {@code StringBuilder} to append the encoded string to
*/
public void encode(byte b, StringBuilder builder) {
builder.append(alphabet[(b >> 4) & 0x0F]).append(alphabet[b & 0x0F]);
}
}