将字符串转换为二进制,然后使用 PHP 再次返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6382738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 00:11:59  来源:igfitidea点击:

Convert string to binary then back again using PHP

phpbinary

提问by locoboy

Is there a way to convert a string to binary then back again in the standard PHP library?

有没有办法将字符串转换为二进制,然后再回到标准 PHP 库中?

To clarify what I'm trying to do is store a password on a database. I'm going to convert it first using a hash function then eventually store it as binary.

为了澄清我想要做的是在数据库中存储密码。我将首先使用哈希函数对其进行转换,然后最终将其存储为二进制文件。



I've found the best way is to use this function. Seems to hash and output in binary at the same time.

我发现最好的方法是使用这个功能。似乎同时以二进制形式散列和输出。

http://php.net/manual/en/function.hash-hmac.php

http://php.net/manual/en/function.hash-hmac.php

回答by Francois Deschenes

You want to use packand base_convert.

您想使用packbase_convert

// Convert a string into binary
// Should output: 0101001101110100011000010110001101101011
$value = unpack('H*', "Stack");
echo base_convert($value[1], 16, 2);

// Convert binary into a string
// Should output: Stack
echo pack('H*', base_convert('0101001101110100011000010110001101101011', 2, 16));

回答by SteeveDroz

Yes, sure!

是的,当然!

There...

那里...

$bin = decbin(ord($char));

... and back again.

……然后又回来了。

$char = chr(bindec($bin));

回答by Stefan Gehrig

A string is just a sequence of bytes, hence it's actually binary data in PHP. What exactly are you trying to do?

字符串只是一个字节序列,因此它实际上是 PHP 中的二进制数据。你到底想做什么?

EDIT

编辑

If you want to store binary data in your database, the problem most often is the column definition in your database. PHP does not differentiate between binary data and strings, but databases do. In MySQL for example you should store binary data in BINARY, VARBINARYor BLOBcolumns.

如果要在数据库中存储二进制数据,最常见的问题是数据库中的列定义。PHP 不区分二进制数据和字符串,但数据库可以。例如,在 MySQL 中,您应该将二进制数据存储在BINARY,VARBINARYBLOB列中。

Another option would be to base64_encodeyour PHP string and store it in some VARCHARor TEXTcolumn in the database. But be aware that the string's length will increase when base64_encodeis used.

另一种选择是将base64_encode您的 PHP 字符串存储在数据库中的某个VARCHARTEXT列中。但请注意,使用时字符串的长度会增加base64_encode

回答by hakre

Your hash is already binary and ready to be used with your database.

您的散列已经是二进制的,可以与您的数据库一起使用。

However you must need to convert it into a format the database column definition expects.

但是,您必须需要将其转换为数据库列定义期望的格式。

Any string in PHP (until 5.3) is a binary string. That means it contains only binary data.

PHP 中的任何字符串(直到 5.3)都是二进制字符串。这意味着它只包含二进制数据。

However because of backwards compatiblity with PHP 6 you can already cast your string explicitly as binary:

但是,由于向后兼容 PHP 6,您已经可以将字符串显式转换为二进制:

 $string = 'my binary string';
 $binary = b'my binary string';

But that is merely for compatibility reasons, in your code you can just do:

但这仅仅是出于兼容性原因,在您的代码中,您可以这样做:

  $string = $binary; // "convert" binary string into string
  $binary = $string  // "convert" string into binary string

Because it's the same. The "convert" is superfluous.

因为它是一样的。“转换”是多余的。

回答by Regis Camimura

easiest way I found was to convert to HEX instead of a string. If it works for you:

我发现的最简单的方法是转换为十六进制而不是字符串。如果它对你有用:

$hex = bin2hex($bin); // It will convert a binary data to its hex representation

$bin = pack("H*" , $hex); // It will convert a hex to binary

OR

或者

$bin = hex2bin($hex); // Available only on PHP 5.4

回答by shoetrax

i was looking for some string bits conversion and got here, If the next case is for you take //it so... if you want to use the bits from a string into different bits maybe this example would help

我正在寻找一些字符串位转换并到了这里,如果下一个案例适合您使用 //它所以...如果您想将字符串中的位用于不同的位,也许这个例子会有所帮助

$string="1001"; //this would be 2^0*1+....0...+2^3*1=1+8=9
$bit4=$string[0];//1
$bit3=$string[1];
$bit2=$string[2];
$bit1=$string[3];//1

回答by MichaelICE

I would most definitely recommend using the built in standard password libraries that come with PHP- Here is a good exampleon how to use them.

我绝对会推荐使用PHP 附带的内置标准密码库- 这是一个关于如何使用它们的好例子



For those coming here to figure out how to go from Binary Strings to Decimals and back, there are some good examples below.

对于那些来这里想弄清楚如何从二进制字符串到十进制并返回的人,下面有一些很好的例子。

For converting binary "strings" to decimals/chars you can do something like this...

要将二进制“字符串”转换为小数/字符,您可以执行以下操作...

echo bindec("00000001") . "\n";
echo bindec("00000010") . "\n";
echo bindec("00000100") . "\n";
echo bindec("00001000") . "\n";
echo bindec("00010000") . "\n";
echo bindec("00100000") . "\n";
echo bindec("01000000") . "\n";
echo bindec("10000000") . "\n";
echo bindec("01000001") . "\n";

# big binary string
echo bindec("111010110111011110000110001")."\n";

The above outputs:

以上输出:

1
2
4
8
16
32
64
128
65
123452465


For converting decimals to char/strings you can do this:

要将小数转换为字符/字符串,您可以执行以下操作:

# convert to binary strings "00000001"
echo decbin(1) . "\n";
echo decbin(2) . "\n";
echo decbin(4) . "\n";
echo decbin(8) . "\n";
echo decbin(16) . "\n";
echo decbin(32) . "\n";
echo decbin(64) . "\n";
echo decbin(128) . "\n";

# convert a ascii character
echo str_pad(decbin(65), 8, 0, STR_PAD_LEFT) ."\n";

# convert a 'char'
echo str_pad(decbin(ord('A')), 8, 0, STR_PAD_LEFT) ."\n";

# big number...
echo str_pad(decbin(65535), 8, 0, STR_PAD_LEFT) ."\n";
echo str_pad(decbin(123452465), 8, 0, STR_PAD_LEFT) ."\n";

The above outputs:

以上输出:

1
10
100
1000
10000
100000
1000000
10000000
01000001
01000001
1111111111111111
111010110111011110000110001

回答by Dojo

Strings in PHP are always BLOBs. So you can use a string to hold the value for your database BLOB. All of this stuff base-converting and so on has to do with presentingthat BLOB.

PHP 中的字符串始终是 BLOB。因此,您可以使用字符串来保存数据库 BLOB 的值。所有这些基础转换等都与呈现BLOB 相关。

If you want a nice human-readable representation of your BLOB then it makes sense to show the bytes it contains, and probably to use hex rather than decimal. Hence, the string "41 42 43" is a good way to presentthe byte array that in C# would be

如果你想要一个很好的人类可读的 BLOB 表示,那么显示它包含的字节是有意义的,并且可能使用十六进制而不是十进制。因此,字符串 "41 42 43" 是表示C# 中的字节数组的好方法

var bytes = new byte[] { 0x41, 0x42, 0x43 };

but it is obviously nota good way to representthose bytes! The string "ABC" is an efficient representation, because it is in fact the same BLOB (only it's not so Large in this case).

但这显然不是表示这些字节的好方法!字符串 "ABC" 是一种有效的表示,因为它实际上是相同的 BLOB(只是在这种情况下它不是那么大)。

In practice you will typically get your BLOBs from functions that return string - such as that hashing function, or other built-in functions like fread.

在实践中,您通常会从返回字符串的函数(例如散列函数或其他内置函数(例如fread))中获取 BLOB 。

In the rare cases (but not so rare when just trying things out/prototyping) that you need to just construct a string from some hard-coded bytes I don't know of anything more efficient than converting a "hex string" to what is often called a "binary string" in PHP:

在极少数情况下(但在尝试/原型设计时并不罕见)您只需要从一些硬编码字节构造一个字符串我不知道有什么比将“十六进制字符串”转换为什么更有效在 PHP 中通常称为“二进制字符串”:

$myBytes = "414243";
$data = pack('H*', $myBytes);

If you var_dump($data);it'll show you string(3) "ABC". That's because 0x41 = 65 decimal = 'A' (in basically all encodings).

如果你var_dump($data);它会告诉你string(3) "ABC"。那是因为 0x41 = 65 十进制 = 'A'(基本上在所有编码中)。

Since looking at binary data by interpreting it as a string is not exactly intuitive, you may want to make a basic wrapper to make debugging easier. One possible such wrapper is

由于通过将二进制数据解释为字符串来查看它并不完全直观,因此您可能需要制作一个基本的包装器来使调试更容易。一种可能的此类包装器是

class blob
{
    function __construct($hexStr = '')
    {
        $this->appendHex($hexStr);
    }

    public $value;

    public function appendHex($hexStr)
    {
        $this->value .= pack('H*', $hexStr);
    }

    public function getByte($index)
    {
        return unpack('C', $this->value{$index})[1];
    }

    public function setByte($index, $value)
    {
        $this->value{$index} = pack('C', $value);
    }

    public function toArray()
    {
        return unpack('C*', $this->value);
    }
}

This is something I cooked up on the fly, and probably just a starting point for your own wrapper. But the idea is to use a string for storage since this is the most efficient structure available in PHP, while providing methods like toArray() for use in debugger watches/evaluations when you want to examine the contents.

这是我即时制作的东西,可能只是您自己的包装器的起点。但我们的想法是使用字符串进行存储,因为这是 PHP 中最有效的结构,同时提供像 toArray() 之类的方法,以便在您想要检查内容时在调试器监视/评估中使用。

Of course you may use a perfectly straightforward PHP array instead and pack it to a string when interfacing with something that uses strings for binary data. Depending on the degree to which you are actually going to modify the blob this may prove easier, and although it isn't space efficient I think you'd get acceptable performance for many tasks.

当然,您可以改用一个非常简单的 PHP 数组,并在与使用字符串表示二进制数据的东西接口时将其打包为字符串。根据您实际要修改 blob 的程度,这可能会更容易,尽管空间效率不高,但我认为您会在许多任务中获得可接受的性能。

An example to illustrate the functionality:

一个说明功能的例子:

// Construct a blob with 3 bytes: 0x41 0x42 0x43.
$b = new blob("414243");

// Append 3 more bytes: 0x44 0x45 0x46.
$b->appendHex("444546");

// Change the second byte to 0x41 (so we now have 0x41 0x41 0x43 0x44 0x45 0x46).
$b->setByte(1, 0x41); // or, equivalently, setByte(1, 65)

// Dump the first byte.
var_dump($b->getByte(0));

// Verify the result. The string "AACDEF", because it's only ASCII characters, will have the same binary representation in basically any encoding.
$ok = $b->value == "AACDEF";

回答by Flip

That's funny how Stefan Gehrig his answer is actually the correct one. You don't need to convert a string into a "011010101" string to store it in BINARY field in a database. Anyway since this is the first answer that comes up when you google for "php convert string to binary string". Here is my contribution to this problem.

有趣的是,Stefan Gehrig 的答案实际上是正确的。您无需将字符串转换为“011010101”字符串即可将其存储在数据库的 BINARY 字段中。无论如何,因为这是您在 Google 上搜索“php 将字符串转换为二进制字符串”时出现的第一个答案。这是我对这个问题的贡献。

The most voted answer by Francois Deschenes goes wrong for long strings (either bytestrings or bitstrings) that is because

Francois Deschenes 投票最多的答案对于长字符串(字节串或位串)来说是错误的,因为

base_convert() may lose precision on large numbers due to properties related to the internal "double" or "float" type used. Please see the Floating point numbers section in the manual for more specific information and limitations.

由于与所使用的内部“double”或“float”类型相关的属性,base_convert() 可能会失去对大数字的精度。有关更多具体信息和限制,请参阅手册中的浮点数部分。

From: https://secure.php.net/manual/en/function.base-convert.php

来自:https: //secure.php.net/manual/en/function.base-convert.php

To work around this limitation you can chop up the input string into chunks. The functions below implement this technique.

要解决此限制,您可以将输入字符串分成多个块。下面的函数实现了这种技术。

<?php

function bytesToBits(string $bytestring) {
  if ($bytestring === '') return '';

  $bitstring = '';
  foreach (str_split($bytestring, 4) as $chunk) {
    $bitstring .= str_pad(base_convert(unpack('H*', $chunk)[1], 16, 2), strlen($chunk) * 8, '0', STR_PAD_LEFT);
  }

  return $bitstring;
}

function bitsToBytes(string $bitstring) {
  if ($bitstring === '') return '';

  // We want all bits to be right-aligned
  $bitstring_len = strlen($bitstring);
  if ($bitstring_len % 8 > 0) {
    $bitstring = str_pad($bitstring, intdiv($bitstring_len + 8, 8) * 8, '0', STR_PAD_LEFT);
  }

  $bytestring = '';
  foreach (str_split($bitstring, 32) as $chunk) {
    $bytestring .= pack('H*', str_pad(base_convert($chunk, 2, 16), strlen($chunk) / 4, '0', STR_PAD_LEFT));
  }

  return $bytestring;
}

for ($i = 0; $i < 10000; $i++) {
  $bytestring_in = substr(hash('sha512', uniqid('', true)), 0, rand(0, 128));
  $bits = bytesToBits($bytestring_in);
  $bytestring_out = bitsToBytes($bits);
  if ($bytestring_in !== $bytestring_out) {
    printf("IN  : %s\n", $bytestring_in);
    printf("BITS: %s\n", $bits);
    printf("OUT : %s\n", $bytestring_out);
    var_dump($bytestring_in, $bytestring_out); // printf() doesn't show some characters ..
    die('Error in functions [1].');
  }
}


for ($i = 0; $i < 10000; $i++) {
  $len = rand(0, 128);
  $bitstring_in = '';
  for ($j = 0; $j <= $len; $j++) {
    $bitstring_in .= (string) rand(0,1);
  }
  $bytes = bitsToBytes($bitstring_in);
  $bitstring_out = bytesToBits($bytes);

  // since converting to byte we always have a multitude of 4, so we need to correct the bitstring_in to compare ..
  $bitstring_in_old = $bitstring_in;
  $bitstring_in_len = strlen($bitstring_in);
  if ($bitstring_in_len % 8 > 0) {
    $bitstring_in = str_pad($bitstring_in, intdiv($bitstring_in_len + 8, 8) * 8, '0', STR_PAD_LEFT);
  }

  if ($bitstring_in !== $bitstring_out) {
    printf("IN1  : %s\n", $bitstring_in_old);
    printf("IN2  : %s\n", $bitstring_in);
    printf("BYTES: %s\n", $bytes);
    printf("OUT  : %s\n", $bitstring_out);
    var_dump($bytes); // printf() doesn't show some characters ..
    die('Error in functions [2].');
  }
}

echo 'All ok!' . PHP_EOL;

Note that if you insert a bitstring that is not a multitude of 8 (example: "101") you will not be able to recover the original bitstring when you converted to bytestring. From the bytestring converting back, uyou will get "00000101" which is numerically the same (unsigned 8 bit integer) but has a different string length. Therefor if the bitstring length is important to you you should save the length in a separate variable and chop of the first part of the string after converting.

请注意,如果您插入的位串不是 8 个(例如:“101”),则在转换为字节串时将无法恢复原始位串。从字节串转换回来,你将得到“00000101”,它在数字上是相同的(无符号 8 位整数),但具有不同的字符串长度。因此,如果位串长度对您很重要,您应该将长度保存在一个单独的变量中,并在转换后截取字符串的第一部分。

$bits_in = "101";
$bits_in_len = strlen($bits_in); // <-- keep track if input length
$bits_out = bytesToBits(bitsToBytes("101"));
var_dump($bits_in, $bits_out, substr($bits_out, - $bits_in_len)); // recover original length with substr

回答by Aashay Trivedi

Why you are using PHP for the conversion. Now, there are so many front end languages available, Why you are still including a server? You can convert the password into the binary number in the front-end and send the converted string in the Database. According to my point of view, this would be convenient.

为什么要使用 PHP 进行转换。现在,有这么多的前端语言可用,为什么你还包括一个服务器?您可以在前端将密码转换为二进制数,并将转换后的字符串发送到数据库中。在我看来,这会很方便。

var bintext, textresult="", binlength;
    this.aaa = this.text_value;
    bintext = this.aaa.replace(/[^01]/g, "");
        binlength = bintext.length-(bintext.length%8);
        for(var z=0; z<binlength; z=z+8) {
            textresult += String.fromCharCode(parseInt(bintext.substr(z,8),2));
                            this.ans = textresult;

This is a Javascript code which I have found here: http://binarytotext.net/, they have used this code with Vue.js. In the code, this.aaa is the v-model dynamic value. To convert the binary into the text values, they have used big numbers. You need to install an additional package and convert it back into the text field. In my point of view, it would be easy.

这是我在此处找到的 Javascript 代码:http: //binarytotext.net/,他们已将此代码与 Vue.js 一起使用。代码中,this.aaa为v-model动态值。为了将二进制转换为文本值,他们使用了大数字。您需要安装一个额外的包并将其转换回文本字段。在我看来,这很容易。