我的android程序有以下方法,用Java编写。
该方法接收一个十六进制字符串,并返回一个用ascii编写的相同文本的字符串。
public static String hexToString(String hex)
{
StringBuilder sb = new StringBuilder();
for (int count = 0; count < hex.length() - 1; count += 2)
{
String output = hex.substring(count, (count + 2)); //grab the hex in pairs
int decimal = Integer.parseInt(output, 16); //convert hex to decimal
sb.append((char)decimal); //convert the decimal to character
}
return sb.toString();
}
该方法运行良好,但我的程序非常耗时,并且该方法可能被调用数万次。当分析我的程序的慢比特时,这种方法占用了太多时间,因为:
Integer.parseInt(output, 16);
和
hex.substring(count, (count + 2));
按最慢优先的顺序。
有人知道实现同样目标的更快方法吗?
不要在每次迭代中创建新的String。提高性能的一种方法是使用char数组并对每个字符应用数学运算。
public static String hexToString(String hex) {
StringBuilder sb = new StringBuilder();
char[] hexData = hex.toCharArray();
for (int count = 0; count < hexData.length - 1; count += 2) {
int firstDigit = Character.digit(hexData[count], 16);
int lastDigit = Character.digit(hexData[count + 1], 16);
int decimal = firstDigit * 16 + lastDigit;
sb.append((char)decimal);
}
return sb.toString();
}
有关此方法的更多信息:
Character#digit
此外,如果您成对解析十六进制字符串,您可以使用@L7ColWinters建议的查找表:
private static final Map<String, Character> lookupHex = new HashMap<String, Character>();
static {
for(int i = 0; i < 256; i++) {
String key = Integer.toHexString(i);
Character value = (char)(Integer.parseInt(key, 16));
lookupHex.put(key, value);
}
}
public static String hexToString(String hex) {
StringBuilder sb = new StringBuilder();
for (int count = 0; count < hex.length() - 1; count += 2) {
String output = hex.substring(count, (count + 2));
sb.append((char)lookupHex.get(output));
}
return sb.toString();
}
这个怎么样。。。
public static String hexToString(final String str) {
return new String(new BigInteger(str, 16).toByteArray());
}
另一种选择是只做一些简单的算法:
public static int hexCharToInt(char c)
{
int result = 0;
if(c >= 'A' && c <= 'F')
{
result += (c - 'A' + 10);
}
else if( c >= '0' && c <= '9')
{
result += (c - '0');
}
return result;
}
public static String hexToString(String hex)
{
StringBuilder sb = new StringBuilder();
for (int count = 0; count < hex.length() - 1; count += 2)
{
char c1 = hex.charAt(count);
char c2 = hex.charAt(count + 1);
int decimal = hexCharToInt(c1) * 16 + hexCharToInt(c2);
sb.append((char)decimal); //convert the decimal to character
}
return sb.toString();
}
试试看哪种解决方案在您的系统上效果最好!
此代码取自Apache Commons Codec的Hex类,并进行了一些简化。(删除了一些范围检查等,这对理解这里来说是不必要的。在实践中,你想使用原始实现。)
/**
* Converts an array of characters representing hexadecimal values into an array of bytes of those same values. The
* returned array will be half the length of the passed array, as it takes two characters to represent any given
* byte. An exception is thrown if the passed char array has an odd number of elements.
*
* @param data
* An array of characters containing hexadecimal digits
* @return A byte array containing binary data decoded from the supplied char array.
* @throws DecoderException
* Thrown if an odd number or illegal of characters is supplied
*/
public static byte[] decodeHex(char[] data) throws DecoderException {
int len = data.length;
byte[] out = new byte[len >> 1];
// two characters form the hex value.
for (int i = 0, j = 0; j < len; i++) {
int f = Character.digit(data[j], 16) << 4;
j++;
f = f | Character.digit(data[j], 16);
j++;
out[i] = (byte) (f & 0xFF);
}
return out;
}
之后可以使用返回的byte[]
来构造String对象。
因此,当使用Apache Commons编解码器时,您的方法如下所示:
public static String hexToString(String hex) throws UnsupportedEncodingException, DecoderException {
return new String(Hex.decodeHex(hex.toCharArray()), "US-ASCII");
}