【问题标题】:PHP convert large Decimal number to HexadecimalPHP将大十进制数转换为十六进制
【发布时间】:2015-06-25 11:36:51
【问题描述】:

我正在使用 php 从证书中提取信息,虽然数据返回正常,但有一个特定值“SerialNumber”以似乎不同的数字格式返回,不确定它是什么..

例如,我期望收到的实际格式是:

‎58 ce a5 e3 63 51 b9 1f 49 e4 7a 20 ce ff 25 0f

但是,我实际上得到的是:

118045041395046077749311747456482878735

这是我执行查找的 php:

$serial = $cert['tbsCertificate']['serialNumber'];

我尝试了几种不同的转换,但都没有以预期的格式返回。

典型证书序列号字段的示例..

VAR 转储

    ["version"]=>
    string(2) "v3"
    ["serialNumber"]=>
    object(Math_BigInteger)#5 (6) {
      ["value"]=>
      string(39) "118045041395046077749311747456482878735"
      ["is_negative"]=>
      bool(false)
      ["generator"]=>
      string(7) "mt_rand"
      ["precision"]=>
      int(-1)
      ["bitmask"]=>
      bool(false)
      ["hex"]=>
      NULL

【问题讨论】:

  • 你是如何从证书中提取信息的?
  • 嗨,Barmer,我在这里使用 phpseclib.. 示例 link,只需点击解码并展开树以获取序列号
  • 我还更新了我的帖子,添加了一个屏幕截图,向您展示典型序列号的样子
  • 您只返回数字值,但您需要一个字母数字返回。您是否尝试过字符串转换结果?试试$serial = (string) $cert['tbsCertificate']['serialNumber']; 但这可能不会做任何事情,因为我们看不到最初设置$cert['tbsCertificate'] 及其子键值的代码,我认为这肯定是真正的问题所在。
  • 是的,没有区别。我什至尝试了 bin2hex() strval() 和其他一些但没有乐趣

标签: php hex decimal bigdecimal phpseclib


【解决方案1】:

您的序列号是Math_BigInteger 对象,如var_dump 所示。 使用toHex 方法以十六进制格式检索包含的数字。 请参阅PEAR website 上的参考资料。

$serial = $cert['tbsCertificate']['serialNumber'];
$valueInHex = $serial->toHex();

注意:十进制格式的 118045041395046077749311747456482878735 等于十六进制格式的 58CEA5E36351B91F49E47A20CEFF250F。您可以使用this 等在线转换器轻松检查。

【讨论】:

  • 我有一个与上述问题无关的问题。我想知道,这些号码叫什么名字:1, 2, 4, 8, 16, 32, 64, 128, 256, ...你知道吗?
【解决方案2】:

这是在不使用外部库的情况下将十进制数转换为十六进制格式的替代解决方案。

$dec = '118045041395046077749311747456482878735';
// init hex array
$hex = array();

while ($dec) {
    // get modulus // based on docs both params are string
    $modulus = bcmod($dec, '16');
    // convert to hex and prepend to array
    array_unshift($hex, dechex($modulus));
    // update decimal number
    $dec = bcdiv(bcsub($dec, $modulus), 16);
}

// array elements to string
echo implode('', $hex);

以及代码的输出...Online Demo

58cea5e36351b91f49e47a20ceff250f

您也可以使用字符串连接代替数组前置。希望这可以帮助。谢谢!

【讨论】:

  • 正如 cmets 所述,OP 已经使用 phpseclibMath_BigIntegerphpseclib 使用,因此我的解决方案不使用任何其他第三方库。您的解决方案遵循了一种糟糕的设计模式,这是“重新发明轮子”的典型案例:Math_BigInteger 类已经包含所需的功能,但您出于某种未知原因拒绝使用它:)
  • @CMate, Math_BigInteger 不是 PHP 核心的一部分,所以它是外部库。您不能简单地将替代代码称为“BAD”并否决LOL。你使用的东西意味着它并不总是最好的。谢谢!
  • 您是否了解Math_BigInteger 已在user3436467 发布的问题中使用?看来你没有。您的解决方案将从 Math_BigInteger 对象获取十进制值并使用您的自定义函数将其转换为十六进制,而不是使用已经存在的 toHex 方法。请仔细阅读原始问题!你的解决方案很糟糕!
  • 备注:我对您的回答投了反对票,因为您将其标记为不是替代方案,而是作为这个问题的更好替代方案,我对此提出异议。我不会撤销我的反对票,因为您编辑了您的答案,然后在您在这里的最后评论中表示我反对您所谓的替代解决方案,这是不正确的。我还不得不向版主报告您的一位 cmets,因为您在其中进行了人身侮辱。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-26
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
相关资源
最近更新 更多