首页 > 编程知识 正文

biginteger是不可变类吗,bigdecimal转换成integer

时间:2023-05-06 00:47:24 阅读:50824 作者:4049

在学习burpsuite的loader-kengen原理时,以下文字通过Java BigInteger显示了输出和pyhon上的不一致

TD q99 QB i3 DTN QQ7RR JL r0 uad oxt 69 su fab/8o 2梦幻红牛0 lsk4/bxkm 58 TP6cuhozeyrvujrm 11 isjhwrv8siom ZJ/rqledlxp1G5 B3 mxfvfjml 9x qz0oczi 33

pyhon上的十进制和十六进制

1277025453552970243334299597815878580699053934731413169127366020167634568078230733712017140453892250828750789770731889872937610609986014310761477129247 34841376044806737149037405159346208103921670369951829058878599971903611447448880396085184296375054850055720027341118913696701387622975160908648039096593040048

0x b5 da BDF 50048 DC3b 67410 eeb 4492 D1 D2 e 01 d 3974 faf 5251 f 001f fc3b 6ce 2d 25 b24 E6 d 790 ce7C4 cfe 9cb a13 b 3798 cab 5426 b 335 d 48 b 09856 aeff 128 a 89 7333 737 eedd 1cc 8d ff7 F8 CFB 853 bb2a 619 fc 2359 d 53822 d 53 d 21 c 59 DEA 8605 c 7020 c 7132 e 1b 8572 AE 42 b 0

在Java下

stringstr=' TD q99 QB i3 DTN QQ7RR JL r0 uad oxt 69 su fab/8o 2梦幻红牛0 lsk4/bxkm 58 TP6cuhozeyyrvujrm 11 isjhwrv8siom ZJ/rqledlxp 1g 5b3mxfvfffff

byte[] data=Base64.getDecoder ().decode ) ) str;

bigintegerb1=newbiginteger (data );

system.out.println(B1;

system.out.println (datatype converter.printhexbinary (B1.to bytearray () );

输出功率

- 5206676813093456439500559297314615291892304210893408934093189692189789761506377018310931093109383109310938 88761502777063777777770150 39283001723086687716447871142873393142172449083131123026127168866247070895014001077827926244452182313294790657245179326250544550856741143926708290527631097168

b5 da BDF 50048 DC3b 67410 eeb 4492 D1 D2 e 01 d 3974 faf 5251 f 001f fc3b 6ce 2d 25 b24 E6 d 790 ce7C4 cfe 9cb a13 b 3798 cab 55426 b 335 d 48 b 09856 aeff 128 a 89 b 39 b 39 737 eedd 1cc 8d ff7 F8 CFB 853 bb2a 619 fc 2359 d 53822 d 5d 21 c 59 DEA 8605 c 7020 c 7132 e 1b 8572 AE 42 b 0

我们发现十六进制的结果是一样的。 只是,十进制的一个是负数,那时以后的结果也无法应对。

有关BigInteger的详细信息,请访问此处。 还介绍了计算机二进制数据编码方案。

这里只是引用了其中的一部分:

存储在计算机中的数值都是补数的形式

正补数与原始代码相同

负补码是把他的原始代码倒过来再加一个

也就是说,补码的补码与原始代码相等

原码、编码比特数值比特,编码比特为0时为正数,编码比特为1时为负数,数值比特为真值的绝对值

根据以上规则再看原文所示的计算步骤:

补数计算步骤

第一步,求原码:首先写出她的原码——码位数值位(绝对值)

步骤2求出反码:

正数时,反码与原始码相同

在为负码的情况下,使原始码相反(除了编码比特以外,按比特反转) )。

步骤3求补数:

如果

是正数 补码与原码一样

如果是负数 补码为反码 + 1

第四步扩充:

如果不足数据类型的宽度,将需要填充到指定宽度

符号位扩充,也就是正数补0  负数补1

总结

不管什么形式,第一位始终都是符号位,0 表示正数, 1表示负数

正数原码/反码/补码 全都一样,知道一种就直接得到另外的形式

负数如果知道补码,想要得到他的原码,只需要对补码再一次的求补码即可

默认原始数据给出的是正数,然而Java没有无符号的类型,没有当做正数处理,我们这里转换一下

//创建一个数组,并添加符号位,正数符号为0,默认数据初始化为0,所以只需把数据复制过去就好了

byte[] test=new byte[data.length+1];

System.arraycopy(data,0,test,1,data.length);

BigInteger b4=new BigInteger(test);

System.out.println(DatatypeConverter.printHexBinary(b4.toByteArray()));

System.out.println(b4);

然后我们看一下输出

127702545355297024333429959781587858069905393473141316912736602016763456807823073371201714045389225082875078977073188987293761060998601431076147712924734841376044806737149037405159346208103921670369951829058878599971903611447448880396085184296375054850055720027341118913696701387622975160908648039096593040048

00B5DABDF50048DC3B67410EEB4492D1D2E01D3974FAF5251F001FFC3B6CE2D25B24E3F6D790CE7C4CFE9CBA13B3798CAB55426B335D48B09856AEFF128A89B327FAEA95E765C7E3F51B90773311557E330BF71433D287198B737EEDD1CC8DFF7F8CFB853BB2A619FC2359D53822D5D21C59DEA8605C7020C7132E1B8572AE42B0

发现10进制数据一致了,也不是负数了,只不过16进制多补了一个符号位0,不影响数值大小。

这样做是不是太麻烦了,自己每次转换,其实有默认的构造方法的,这里可以传入1和-1代表正负数

BigInteger b2 = new BigInteger(1, data);

System.out.println(b2);

System.out.println(DatatypeConverter.printHexBinary(b2.toByteArray()));

输出是一致的

127702545355297024333429959781587858069905393473141316912736602016763456807823073371201714045389225082875078977073188987293761060998601431076147712924734841376044806737149037405159346208103921670369951829058878599971903611447448880396085184296375054850055720027341118913696701387622975160908648039096593040048

00B5DABDF50048DC3B67410EEB4492D1D2E01D3974FAF5251F001FFC3B6CE2D25B24E3F6D790CE7C4CFE9CBA13B3798CAB55426B335D48B09856AEFF128A89B327FAEA95E765C7E3F51B90773311557E330BF71433D287198B737EEDD1CC8DFF7F8CFB853BB2A619FC2359D53822D5D21C59DEA8605C7020C7132E1B8572AE42B0

下面验证一下补码计算,创建一个负数的,然后通过b2正数的来计算一下这个负数的,比较一下结果

BigInteger b3 = new BigInteger(-1, data);

System.out.println(b3);

System.out.println(DatatypeConverter.printHexBinary(b3.toByteArray()));

BigInteger b6 = b2.not().add(BigInteger.ONE);

System.out.println(b6);

System.out.println(DatatypeConverter.printHexBinary(b6.toByteArray()));

--------------b3--------------

-127702545355297024333429959781587858069905393473141316912736602016763456807823073371201714045389225082875078977073188987293761060998601431076147712924734841376044806737149037405159346208103921670369951829058878599971903611447448880396085184296375054850055720027341118913696701387622975160908648039096593040048

FF4A25420AFFB723C498BEF114BB6D2E2D1FE2C68B050ADAE0FFE003C4931D2DA4DB1C09286F3183B3016345EC4C867354AABD94CCA2B74F67A95100ED75764CD805156A189A381C0AE46F88CCEEAA81CCF408EBCC2D78E6748C81122E3372008073047AC44D59E603DCA62AC7DD2A2DE3A621579FA38FDF38ECD1E47A8D51BD50

--------------b6--------------

-127702545355297024333429959781587858069905393473141316912736602016763456807823073371201714045389225082875078977073188987293761060998601431076147712924734841376044806737149037405159346208103921670369951829058878599971903611447448880396085184296375054850055720027341118913696701387622975160908648039096593040048

FF4A25420AFFB723C498BEF114BB6D2E2D1FE2C68B050ADAE0FFE003C4931D2DA4DB1C09286F3183B3016345EC4C867354AABD94CCA2B74F67A95100ED75764CD805156A189A381C0AE46F88CCEEAA81CCF408EBCC2D78E6748C81122E3372008073047AC44D59E603DCA62AC7DD2A2DE3A621579FA38FDF38ECD1E47A8D51BD50

二者结果一致,所以说明Java BigInteger处理byte[]数组时直接把数据存储的,没有符号位的概念。我们要么构造的时候传入符号位的参数,要么自己添加数组符号位。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。