【问题标题】:Java: Retain leading zero in outputJava:在输出中保留前导零
【发布时间】:2017-04-03 09:20:03
【问题描述】:

我有一个创建字节数组0x00 0x02 0x03 0x00 的Java 程序。我将其转换为BigInteger 类型。但是当我将它重新转换为字节数组时,我得到的输出没有前导零2 3 0。以下是代码:

byte[] b = new byte[] {0x00, 0x02, 0x03, 0x00};
BigInteger b1 = new BigInteger(b);
byte[] b2 = b1.toByteArray();

for (byte aB2 : b2) 
    System.out.print(aB2 + " ");

如何保留前导零?

谢谢。

【问题讨论】:

  • 打印b数组有前导0??
  • 这是设计使然。 0100 因为 int 是 100 并且将其设置为 String 将是 100 而没有前导 0。
  • 像这样通过BigInteger 发送byte[] 有什么意义?你知道b1 不是号码230,对吧?这是131840。那么为什么你会期望数字131840 是二进制补码字节0x00 0x02 0x03 0x00?为什么不期待0x00 0x00 0x00 0x02 0x03 0x00?由于BigInteger 存储了数字131840,它只会以您要求的任何表示形式返回该值,而没有any 前导零。为什么你会期望它添加前导零?应该输出多少?
  • 这与这个问题有什么关系?如果您需要构建一个特定的 5 字节序列,为什么要使用 BigInteger 并转换为/从 two's-complement 转换?你知道那是什么吗?
  • PKCS#1 填充中的前导零只是虚构的,强调被取幂的整数严格小于模数。

标签: java rsa padding


【解决方案1】:

你不能。 BigInteger 不存储该信息。

public BigInteger(byte[] val) {
    if (val.length == 0)
        throw new NumberFormatException("Zero length BigInteger");

    if (val[0] < 0) {
        mag = makePositive(val);
        signum = -1;
    } else {
        mag = stripLeadingZeroBytes(val);     // (!) <-- watch this
        signum = (mag.length == 0 ? 0 : 1);
    }
    if (mag.length >= MAX_MAG_LENGTH) {
        checkRange();
    }
}

【讨论】:

  • 但我想检查是否有前导零。那我该怎么做呢?
  • 那么您应该将数据存储在保留该数据的结构中。例如。您可以保留原始字节数组或发明一个布尔标志,告诉您是否有前导零并在以后重用。
【解决方案2】:

如果您知道需要多少字节,则可以非常简单地解决此问题,只需将它们添加回输出 byte[]

在 Kotlin 中,这看起来像:

fun BigInteger.byteArrayPaddedToSize(size: Int): ByteArray {
    val byteArrayRepresentation = toByteArray().takeLast(size).toByteArray()
    return if (byteArrayRepresentation.size == size) {
        byteArrayRepresentation
    } else {
        val difference = size - byteArrayRepresentation.size
        ByteArray(difference) { 0x00 } + byteArrayRepresentation
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    相关资源
    最近更新 更多