java BigInteger.toString 方法正在删除前导 0

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10275769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 00:20:50  来源:igfitidea点击:

BigInteger.toString method is deleting leading 0

javatostringbiginteger

提问by Dheeraj Joshi

I am trying to generate MD5 sum using MessageDigest. And i am having following code.

我正在尝试使用 MessageDigest 生成 MD5 总和。我有以下代码。

byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);

This returns not 32 character string but a 31 character string 8611c0b0832bce5a19ceee626a403a7

这返回的不是 32 个字符的字符串,而是一个 31 个字符的字符串 8611c0b0832bce5a19ceee626a403a7

Expected String is 08611c0b0832bce5a19ceee626a403a7

预期字符串是 08611c0b0832bce5a19ceee626a403a7

Leading 0 is missing in the output.

输出中缺少前导 0。

I tried the other method

我尝试了另一种方法

byte[] md5sum = digest.digest();
output = new String(Hex.encodeHex(md5sum));

And the output is as expected.

并且输出符合预期。

I checked the doc and Integer.toString does the conversion according to it

我检查了文档,Integer.toString 根据它进行了转换

The digit-to-character mapping provided by Character.forDigit is used, and a minus sign is prepended if appropriate.

使用 Character.forDigit 提供的数字到字符映射,并在适当的情况下添加减号。

and in Character.forDigit methos

并在 Character.forDigit 方法中

The digit argument is valid if 0 <=digit < radix.

如果 0 <=digit < radix,则 digit 参数有效。

Can some one tell me how two methods are different and why leading 0 is deleted?

有人可以告诉我两种方法有何不同以及为什么删除前导 0 吗?

采纳答案by Jon Skeet

I would personally avoidusing BigIntegerto convert binary data to text. That's not really what it's there for, even if it canbe used for that. There's loads of code available to convert a byte[]to its hex representation - e.g. using Apache Commons Codecor a simple single method:

我个人会避免使用BigInteger将二进制数据转换为文本。这并不是它的真正用途,即使它可以用于那个。有大量代码可用于将 a 转换byte[]为其十六进制表示 - 例如使用Apache Commons Codec或简单的单一方法:

private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
public static String toHex(byte[] data) {
    char[] chars = new char[data.length * 2];
    for (int i = 0; i < data.length; i++) {
        chars[i * 2] = HEX_DIGITS[(data[i] >> 4) & 0xf];
        chars[i * 2 + 1] = HEX_DIGITS[data[i] & 0xf];
    }
    return new String(chars);
}

回答by Gorets

String.format("%064X", new BigInteger(1, hmac.doFinal(message.getBytes())));

String.format("%064X", new BigInteger(1, hmac.doFinal(message.getBytes())));

where

在哪里

  1. 0 - zero leading sign
  2. 64 - string length
  3. X - Uppercase
  1. 0 - 零前导符号
  2. 64 - 字符串长度
  3. X - 大写

回答by paxdiablo

It's deleted because the leading zero is not significant, according to BigInteger. There is no difference between 27and 000000000027.

根据 ,它被删除是因为前导零不重要BigInteger27和之间没有区别000000000027

If you want a specific length, you'll have to force it yourself, with something like:

如果你想要一个特定的长度,你必须自己强迫它,比如:

output = ("00000000000000000000000000000000"+output).substring(output.length());

(kludgy though that is).

(虽然很笨拙)。

回答by user1689394

The deleted zero is replaced using this code:

使用以下代码替换已删除的零:

MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(output.getBytes());
byte[] outDigest = digest.digest();
BigInteger outBigInt = new BigInteger(1,outDigest);
output = outBigInt.toString(16);
    while (output.length() < 32){
    output = "0"+output;
    }

loop will account for as many leading zeros as needed

循环将根据需要考虑尽可能多的前导零

回答by Aram

MessageDigest m=MessageDigest.getInstance("MD5");
m.update(PlainText.getBytes(),0,PlainText.length());
String M1=new BigInteger(1,m.digest()).toString(16);      
return M1;