在 Java 中将字符串转换为十六进制
Posted
技术标签:
【中文标题】在 Java 中将字符串转换为十六进制【英文标题】:Converting A String To Hexadecimal In Java 【发布时间】:2010-10-29 18:15:09 【问题描述】:我正在尝试在 java 中将“testing123”之类的字符串转换为十六进制形式。我目前正在使用 BlueJ。
而将其转换回来,除了向后转换之外,它是一样的吗?
【问题讨论】:
【参考方案1】:这是将其转换为十六进制的简单方法:
public String toHex(String arg)
return String.format("%040x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
【讨论】:
+1 到我见过的最纯净的 3vilness 样本:使用 BigInteger 从 byte[] 转换... 爱它!没有循环,也没有位翻转。我想给你 0xFF 赞成票 :) 为确保 40 个字符,应添加零填充: return String.format("%040x", new BigInteger(arg.getBytes(/*YOUR_CHARSET?*/))); @Kaleb 您知道是否可以将结果字符串转换回来?如果,是的,你能给我一些提示吗?谢谢! 你必须使用BigInteger(int,byte[])
构造函数;否则,如果第一个字节为负数,您将得到一个负数 BigInteger。【参考方案2】:
为确保十六进制长度始终为 40 个字符,BigInteger 必须为正数:
public String toHex(String arg)
return String.format("%x", new BigInteger(1, arg.getBytes(/*YOUR_CHARSET?*/)));
【讨论】:
这个方法其实是正确的。试试byte[] data = -1, 1 ;
——这个答案中的代码工作正常,而有 17 个赞成票的代码会失败。
是否可以从字符串中获取值为-1
的字节(如示例中所要求的)?
@KalebPederson Yes. It's not even very hard.。如果您选择的编码曾经使用任何字符的最高有效位(例如,像 UTF-* 那样),则您的数组中有负的byte
s。【参考方案3】:
import org.apache.commons.codec.binary.Hex;
...
String hexString = Hex.encodeHexString(myString.getBytes(/* charset */));
http://commons.apache.org/codec/apidocs/org/apache/commons/codec/binary/Hex.html
【讨论】:
有趣,如果你不想重新发明***的话。 @MelNicholson Hex 中有一个 decodeHex 函数可以转到一个字节 []。您需要使用它,因为没有任何东西可以保证随机 HEX 字符串可以转换为您的编码中的字符串。【参考方案4】:您编码为十六进制的数字必须代表字符的某种编码,例如 UTF-8。所以首先将 String 转换为 byte[] 表示该编码中的字符串,然后将每个字节转换为十六进制。
public static String hexadecimal(String input, String charsetName) throws UnsupportedEncodingException
if (input == null) throw new NullPointerException();
return asHex(input.getBytes(charsetName));
private static final char[] HEX_CHARS = "0123456789abcdef".toCharArray();
public static String asHex(byte[] buf)
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
return new String(chars);
【讨论】:
这是一个有趣的解决方案,它触及了数据数字表示的核心。您能否解释一下您在做什么,以及您的解决方案中的“神奇数字”代表什么?新手可能不知道 >>> 运算符的含义,为什么我们使用按位与 & 以及 0xF0 的掩码,或者为什么 chars 数组的大小为 [2 * buf.length]。【参考方案5】:使用DatatypeConverter.printHexBinary()
:
public static String toHexadecimal(String text) throws UnsupportedEncodingException
byte[] myBytes = text.getBytes("UTF-8");
return DatatypeConverter.printHexBinary(myBytes);
示例用法:
System.out.println(toHexadecimal("Hello ***"));
打印:
48656C6C6F20537461636B4F766572666C6F77
注意:这会给Java 9
和更高版本带来一些额外的麻烦,因为默认情况下不包含 API。供参考,例如见thisGitHub
问题。
【讨论】:
【参考方案6】:这里有另一个解决方案
public static String toHexString(byte[] ba)
StringBuilder str = new StringBuilder();
for(int i = 0; i < ba.length; i++)
str.append(String.format("%x", ba[i]));
return str.toString();
public static String fromHexString(String hex)
StringBuilder str = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2)
str.append((char) Integer.parseInt(hex.substring(i, i + 2), 16));
return str.toString();
【讨论】:
很好,但我会使用format("%02x")
所以 format() 总是使用 2 个字符。即使 ASCII 是两位十六进制,即 A=0x65【参考方案7】:
所有基于 String.getBytes() 的答案都涉及根据字符集编码您的字符串。您不一定会获得组成字符串的 2 字节 characters 的十六进制值。如果您真正想要的是相当于十六进制查看器,那么您需要直接访问字符。这是我在代码中用于调试 Unicode 问题的函数:
static String stringToHex(String string)
StringBuilder buf = new StringBuilder(200);
for (char ch: string.toCharArray())
if (buf.length() > 0)
buf.append(' ');
buf.append(String.format("%04x", (int) ch));
return buf.toString();
然后,stringToHex("testing123") 会给你:
0074 0065 0073 0074 0069 006e 0067 0031 0032 0033
【讨论】:
如果您想要查看 Java 字符的内部表示,即 UTF-16,Unicode 的特定表示,这很好。 这会打印前导零,即使它们实际上不在内存中。 Java 确实 not 不再使用 UTF-16。【参考方案8】:获取十六进制的整数值
//hex like: 0xfff7931e to int
int hexInt = Long.decode(hexString).intValue();
【讨论】:
【参考方案9】:byte[] bytes = string.getBytes(CHARSET); // you didn't say what charset you wanted
BigInteger bigInt = new BigInteger(bytes);
String hexString = bigInt.toString(16); // 16 is the radix
此时您可以返回hexString
,但需要注意的是,前导空字符将被剥离,如果第一个字节小于 16,则结果将具有奇数长度。如果您需要处理这些情况,您可以添加一些额外的代码来填充 0:
StringBuilder sb = new StringBuilder();
while ((sb.length() + hexString.length()) < (2 * bytes.length))
sb.append("0");
sb.append(hexString);
return sb.toString();
【讨论】:
【参考方案10】:将字母转换成十六进制代码和十六进制代码转换成字母。
String letter = "a";
String code;
int decimal;
code = Integer.toHexString(letter.charAt(0));
decimal = Integer.parseInt(code, 16);
System.out.println("Hex code to " + letter + " = " + code);
System.out.println("Char to " + code + " = " + (char) decimal);
【讨论】:
【参考方案11】:我建议这样,str
是您的输入字符串:
StringBuffer hex = new StringBuffer();
char[] raw = tokens[0].toCharArray();
for (int i=0;i<raw.length;i++)
if (raw[i]<=0x000F) hex.append("000");
else if(raw[i]<=0x00FF) hex.append("00" );
else if(raw[i]<=0x0FFF) hex.append("0" );
hex.append(Integer.toHexString(raw[i]).toUpperCase());
【讨论】:
感谢软件猴子的指正。写答案的时候我已经很累了,我对 'raw[i] 这真的很好用,有没有办法将生成的十六进制再次反转回字符串? str在哪里?【参考方案12】:反之亦然(十六进制转字符串),您可以使用
public String hexToString(String hex)
return new String(new BigInteger(hex, 16).toByteArray());
【讨论】:
【参考方案13】:首先使用 getBytes() 函数将其转换为字节,然后将其转换为十六进制使用:
private static String hex(byte[] bytes)
StringBuilder sb = new StringBuilder();
for (int i=0; i<bytes.length; i++)
sb.append(String.format("%02X ",bytes[i]));
return sb.toString();
【讨论】:
【参考方案14】:使用来自多个线程的多人帮助..
我知道这个问题已经得到解答,但我想为处于相同情况的任何其他人提供完整的编码和解码方法..
这是我的编码和解码方法..
// Global Charset Encoding
public static Charset encodingType = StandardCharsets.UTF_8;
// Text To Hex
public static String textToHex(String text)
byte[] buf = null;
buf = text.getBytes(encodingType);
char[] HEX_CHARS = "0123456789abcdef".toCharArray();
char[] chars = new char[2 * buf.length];
for (int i = 0; i < buf.length; ++i)
chars[2 * i] = HEX_CHARS[(buf[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[buf[i] & 0x0F];
return new String(chars);
// Hex To Text
public static String hexToText(String hex)
int l = hex.length();
byte[] data = new byte[l / 2];
for (int i = 0; i < l; i += 2)
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
String st = new String(data, encodingType);
return st;
【讨论】:
不错!仅在第 13 行,“>>>”应该是“>>”【参考方案15】:单行 HEX 编码/解码,无需外部库(Java 8 及更高版本):
编码:
String hexString = inputString.chars().mapToObj(c ->
Integer.toHexString(c)).collect(Collectors.joining());
解码:
String decodedString = Stream.iterate(0, i -> i+2)
.limit(hexString.length()/2 + Math.min(hexString.length()%2,1))
.map(i -> "" + (char)Integer.parseInt("" + hexString.charAt(i) + hexString.charAt(i+1),16))
.collect(Collectors.joining());
【讨论】:
【参考方案16】:将字符串转换为十六进制:
public String hexToString(String hex)
return Integer.toHexString(Integer.parseInt(hex));
这绝对是最简单的方法。
【讨论】:
这不是解决方案。问题是问如何获取任意String内容的十六进制表示,并专门提供了"testing123"作为例子。【参考方案17】:好多了:
public static String fromHexString(String hex, String sourceEncoding ) throws IOException
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] buffer = new byte[512];
int _start=0;
for (int i = 0; i < hex.length(); i+=2)
buffer[_start++] = (byte)Integer.parseInt(hex.substring(i, i + 2), 16);
if (_start >=buffer.length || i+2>=hex.length())
bout.write(buffer);
Arrays.fill(buffer, 0, buffer.length, (byte)0);
_start = 0;
return new String(bout.toByteArray(), sourceEncoding);
【讨论】:
【参考方案18】:import java.io.*;
import java.util.*;
public class Exer5
public String ConvertToHexadecimal(int num)
int r;
String bin="\0";
do
r=num%16;
num=num/16;
if(r==10)
bin="A"+bin;
else if(r==11)
bin="B"+bin;
else if(r==12)
bin="C"+bin;
else if(r==13)
bin="D"+bin;
else if(r==14)
bin="E"+bin;
else if(r==15)
bin="F"+bin;
else
bin=r+bin;
while(num!=0);
return bin;
public int ConvertFromHexadecimalToDecimal(String num)
int a;
int ctr=0;
double prod=0;
for(int i=num.length(); i>0; i--)
if(num.charAt(i-1)=='a'||num.charAt(i-1)=='A')
a=10;
else if(num.charAt(i-1)=='b'||num.charAt(i-1)=='B')
a=11;
else if(num.charAt(i-1)=='c'||num.charAt(i-1)=='C')
a=12;
else if(num.charAt(i-1)=='d'||num.charAt(i-1)=='D')
a=13;
else if(num.charAt(i-1)=='e'||num.charAt(i-1)=='E')
a=14;
else if(num.charAt(i-1)=='f'||num.charAt(i-1)=='F')
a=15;
else
a=Character.getNumericValue(num.charAt(i-1));
prod=prod+(a*Math.pow(16, ctr));
ctr++;
return (int)prod;
public static void main(String[] args)
Exer5 dh=new Exer5();
Scanner s=new Scanner(System.in);
int num;
String numS;
int choice;
System.out.println("Enter your desired choice:");
System.out.println("1 - DECIMAL TO HEXADECIMAL ");
System.out.println("2 - HEXADECIMAL TO DECIMAL ");
System.out.println("0 - EXIT ");
do
System.out.print("\nEnter Choice: ");
choice=s.nextInt();
if(choice==1)
System.out.println("Enter decimal number: ");
num=s.nextInt();
System.out.println(dh.ConvertToHexadecimal(num));
else if(choice==2)
System.out.println("Enter hexadecimal number: ");
numS=s.next();
System.out.println(dh.ConvertFromHexadecimalToDecimal(numS));
while(choice!=0);
【讨论】:
【参考方案19】:new BigInteger(1, myString.getBytes(/*YOUR_CHARSET?*/)).toString(16)
【讨论】:
【参考方案20】:Here are some benchmarks 比较不同的方法和库。 Guava 在解码方面击败了 Apache Commons Codec。 Commons Codec 在编码方面击败了 Guava。 JHex 在解码和编码方面都胜过他们。
JHex 示例
String hexString = "596f752772652077656c636f6d652e";
byte[] decoded = JHex.decodeChecked(hexString);
System.out.println(new String(decoded));
String reEncoded = JHex.encode(decoded);
所有内容都在single class file for JHex 中。如果您不想在依赖关系树中添加另一个库,请随意复制粘贴。另请注意,在我弄清楚如何使用 Gradle 和 Bintray 插件发布多个发布目标之前,它只能作为 Java 9 jar 使用。
【讨论】:
【参考方案21】:检查此解决方案是否将 String to hex 和 hex to String 反之亦然
public class TestHexConversion
public static void main(String[] args)
try
String clearText = "testString For;0181;with.love";
System.out.println("Clear Text = " + clearText);
char[] chars = clearText.toCharArray();
StringBuffer hex = new StringBuffer();
for (int i = 0; i < chars.length; i++)
hex.append(Integer.toHexString((int) chars[i]));
String hexText = hex.toString();
System.out.println("Hex Text = " + hexText);
String decodedText = HexToString(hexText);
System.out.println("Decoded Text = "+decodedText);
catch (Exception e)
e.printStackTrace();
public static String HexToString(String hex)
StringBuilder finalString = new StringBuilder();
StringBuilder tempString = new StringBuilder();
for( int i=0; i<hex.length()-1; i+=2 )
String output = hex.substring(i, (i + 2));
int decimal = Integer.parseInt(output, 16);
finalString.append((char)decimal);
tempString.append(decimal);
return finalString.toString();
输出如下:
明文 = testString For;0181;with.love
十六进制文本 = 74657374537472696e6720466f723b303138313b776974682e6c6f7665
解码文本 = testString For;0181;with.love
【讨论】:
【参考方案22】:将字符串转换为其十六进制表示法的一种简便的方法是:
public static void main(String... args)
String str = "Hello! This is test string.";
char ch[] = str.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ch.length; i++)
sb.append(Integer.toHexString((int) ch[i]));
System.out.println(sb.toString());
【讨论】:
以上是关于在 Java 中将字符串转换为十六进制的主要内容,如果未能解决你的问题,请参考以下文章