【问题标题】:Convert a binary number to Base 64将二进制数转换为 Base 64
【发布时间】:2011-09-30 08:04:19
【问题描述】:

我知道这是一个非常愚蠢的问题,但我不知道该怎么做。

我有一个任意的二进制数,比如说,

1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111

我想使用 PHP 将它转换为 Base 64 - 我尝试的每一种方式都会给我不同的结果。甚至不同的在线转换器也会以不同的方式对其进行转换:

http://home2.paulschou.net/tools/xlate/
http://convertxy.com/index.php/numberbases/

PHP 的 base_convert 仅适用于 base36,而 base64_encode 需要一个字符串。

我该怎么办?

UPDATE:我实现了@binaryLV建议的解决方案功能,效果很好。

但是,我将结果与 PHP 的内置 base_convert 进行了比较。事实证明,base_convert to base36 返回的值比自定义 base64 函数更短! (是的,我确实在所有二进制数前面加上了“1”,以确保前导零不会丢失)。

我也注意到,base_convert 对于大量数字非常不准确。所以我需要一个像base_convert一样工作的函数,但准确,最好是64进制。

【问题讨论】:

  • 1) 想要将数字直接转换为base 64? - 2) 想要先将二进制数转换为 ASCII,然后再转换为基数 64? 3)还是什么?
  • @Mido - 我真的看不出 (1) 和 (2) 之间有什么区别 - 对我来说重要的是结果。我希望能够以一致的方式将二进制数(不是'0'和'1'的字符串)转换为base 64,然后能够将其转换回二进制。

标签: php base64


【解决方案1】:

示例中字符串的长度为 160。这让我觉得它包含大约 160/8 个字符的信息。所以,

  1. 将字符串拆分成部分,每个部分包含8个二进制数字并描述单个字符
  2. 将每个部分转换为十进制整数
  3. 从字符构建字符串,这些字符由第二步中的 ASCII 代码组成

这适用于大小为n*8 的字符串。对于其他字符串(例如,12 个二进制数字),它会给出意想不到的结果。

代码:

function bin2base64($bin) {
    $arr = str_split($bin, 8);
    $str = '';
    foreach ( $arr as $binNumber ) {
        $str .= chr(bindec($binNumber));
    }
    return base64_encode($str);
}

$bin = '1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111';
echo bin2base64($bin);

结果:

kDICQIMBEFjDBxwMBJiAASBYwgc=

这里还有将其解码回二进制数字字符串的函数:

function base64bin($str) {
    $result = '';
    $str = base64_decode($str);
    $len = strlen($str);
    for ( $n = 0; $n < $len; $n++ ) {
        $result .= str_pad(decbin(ord($str[$n])), 8, '0', STR_PAD_LEFT);
    }
    return $result;
}

var_dump(base64bin(bin2base64($bin)) === $bin);

结果:

boolean true

【讨论】:

  • 我认为可以。谢谢(:
  • @egasimus,我也添加了 decoder,所以你可以用两种方式转换它们。如果您喜欢,请随意对答案进行投票 :) 啊,我忘了警告字符串的长度必须是 n*8,也就是说,具有 12 个二进制数字的字符串会产生意想不到的结果。
  • 很抱歉不接受您的回答 - 我将您的函数与 base36 中的 base_convert 进行了比较;对于“100000011111110100000000”,您的函数返回“gf0AAA==”,base_convert(36) 返回“52L8G”(或没有最后 4 个零的“投注”,它们只是填充)。所以显然有更好的解决方案,我决心找到它。 :)
  • @egasimus,我得到的是“gf0A”,而不是“GF0AA==”。如果您确切地告诉您要实现的目标,那么提供帮助也会更容易,因为“更好的解决方案”是非常通用的术语。例如,100% 一致且可靠的结果对我来说似乎是足够好的解决方案。
  • 这很好用。如果您想避免 = 符号,只需确保 0 和 1 的数量是 24 的倍数(每个 ASCII 字符 8 位,每个 base 64 字符 6 位)当您在 base64 中创建最终字符时会出现等号,但您没有正确的位数。
【解决方案2】:

PHP 具有内置的 base 64 编码功能,请参阅文档here。如果你想二进制字符串的十进制值首先使用bin2dec,顺便说一下十六进制也有类似的功能。文档是您的朋友。

[编辑]

我可能误解了您的问题,如果您想在实际基数(基数 2 和 64)之间进行转换,请使用 base_convert

【讨论】:

  • base_convert() 对大数字不精确,它甚至无法在 32 位系统上处理 32 位数字。 bin2dec() 也不应用于大数字。
  • @binaryLV:确实,根据 PHP.net 上函数页面上的警告
【解决方案3】:
$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
echo base64_encode ($number);

如果您希望将确切的字符串转换为 Base 64。

【讨论】:

  • 这里,$number 被解释为十进制数,而不是二进制数。
【解决方案4】:

要将二进制数(2 进制)转换为 64 进制,请使用base_convert function

$number = 1001000000110010000000100100000010000011000000010001000001011000110000110000011100011100000011000000010010011000100000000000000100100000010110001100001000000111;
base_convert ($number , 2, 64);

【讨论】:

  • base_convert 只接受 2 到 36 之间的参数。
  • @Meglio 确实如此。当我回答这个问题时,我可能应该注意到这一点。
猜你喜欢
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
  • 2016-04-18
  • 1970-01-01
  • 2017-02-05
  • 2014-02-26
相关资源
最近更新 更多