【问题标题】:Convert bytes to int and back java/python将字节转换为 int 并返回 java/python
【发布时间】:2019-05-06 13:31:06
【问题描述】:

我正在转换一个任意的 ascii 字符串,它是一个用零填充的数字,例如“1”为“0000000001”,然后转换为字节,然后在 python 中返回。当然该值也可以是“0000004231”等。它始终是数字,并且在用零填充的有符号 32 位值范围内。

当我告诉 python 它是字节并且我希望它是 int 时,它会将它转换为一个漂亮的大随机数。然后我可以稍后使用to_bytes() 函数将其转换回原始值。

In [74]: value = int.from_bytes(bytes(format(1, '010d'),'ascii'), byteorder='little')                                                                                                                                                                                          

In [75]: value.to_bytes(10,byteorder=sys.byteorder)                                                                                                                                                                                                                            
Out[75]: b'0000000001'

In [76]: value                                                                                                                                                                                                                                                                 
Out[76]: 232284873704446901628976

In [77]: 

如何使用 java 实现相同的功能?

【问题讨论】:

  • 您能指定第一行(contents="ascii"?)和第二行(内容主要是 ASCII '0')中的value 之间的区别吗?你能指定这个数字有什么相关性吗?该数字是仅前八个 ASCII '0' 的十进制表示,并丢弃尾随的两个。
  • 我需要用零和 10 个字符填充数字。它是一个 32 位有符号整数范围内的数字,填充到固定 10 个字符长度
  • '漂亮的大随机数'触发了我的警报。对您来说,它可能看起来是随机的,但在十六进制(对计算机而言)它看起来像 0x3030303030303030。 (0x30 是“数字零”的 ASCII 码)您是否看到 0000000001 与 0000000099 具有相同的数字?这个号码的目的是什么?这听起来像是典型的XY problem
  • 0000000001 与 0000000099 相同是什么意思。1 => 232284873704446901628976 和 99 => 270229826264067449303088 不一样?目的是让一个固定长度的数字变成另一个固定长度的更长的数字,你一眼就认不出来。不过没关系...
  • 啊我的错。该计算器支持大整数,但显然将十六进制限制为 64 位。要获得任何字符串的“随机数”,只需使用string.hashCode()

标签: java python int byte


【解决方案1】:

Java 代码的精确(?)功能副本:

String string = String.format("%010d", 1); // I hope this format is correct

byte[] bigEndian    = string.getBytes(StandardCharsets.US_ASCII);
System.out.println(Arrays.toString(bigEndian)); // [48, 48, 48, 48, 48, 48, 48, 48, 48, 49]

byte[] littleEndian = new byte[bigEndian.length];
for (int i = 0; i < bigEndian.length; i++)
    littleEndian[littleEndian.length - i - 1] = bigEndian[i];

BigInteger value = new BigInteger(littleEndian);
System.out.println(value); // 232284873704446901628976

然后返回:

BigInteger value = new BigInteger("232284873704446901628976");

byte[] littleEndian = value.toByteArray();

byte[] bigEndian = new byte[littleEndian.length];
for (int i = 0; i < littleEndian.length; i++)
    bigEndian[bigEndian.length - i - 1] = littleEndian[i];

System.out.println(Arrays.toString(bigEndian)); // [48, 48, 48, 48, 48, 48, 48, 48, 48, 49]

String string = new String(bigEndian, StandardCharsets.US_ASCII);
System.out.println(string); // 0000000001

int number = Integer.parseInt(string);
System.out.println(number); // 1

无论如何,如果你让python代码使用big-endian,你可以跳过Java中的数组反转。

【讨论】:

  • 这似乎完全一样。谢谢
【解决方案2】:

我不擅长 Python,但可能是这样的:

String test = "0000000001";
byte[] testBytes = test.getBytes(); // If needed pass an encoding as argument
String newTest = new String(testBytes); // Again, if needed, pass an encoding as argument

【讨论】:

  • 我已经试过了。我在testBytes 变量中得到[B@7852e922,而不是我期望的232284873704446901628976
猜你喜欢
  • 2016-06-22
  • 2011-04-10
  • 2018-09-17
  • 2011-11-16
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
相关资源
最近更新 更多