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
9 个解决方案
#1
47
You want to use pack
and base_convert
.
您需要使用pack和base_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));
#2
26
Yes, sure!
是的,当然!
There...
在那里……
$bin = decbin(ord($char));
... and back again.
…和回来。
$char = chr(bindec($bin));
#3
9
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
, VARBINARY
or BLOB
columns.
如果希望在数据库中存储二进制数据,最常见的问题是数据库中的列定义。PHP不区分二进制数据和字符串,但是数据库可以。例如,在MySQL中,应该将二进制数据存储在二进制、VARBINARY或BLOB列中。
Another option would be to base64_encode
your PHP string and store it in some VARCHAR
or TEXT
column in the database. But be aware that the string's length will increase when base64_encode
is used.
另一个选项是对PHP字符串进行base64_encode并将其存储在数据库中的某个VARCHAR或文本列中。但是请注意,当使用base64_encode时,字符串的长度将会增加。
#4
3
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.
因为它是相同的。“转换”是多余的。
#5
3
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
#6
0
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
#7
0
I would most definitely recommend using the built in standard password libraries that come with PHP - Here is a good example on 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
#8
0
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 presenting that 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 present the byte array that in C# would be
如果您想要一个良好的人类可读的BLOB表示,那么显示它包含的字节是有意义的,并且可能使用十六进制而不是十进制。因此,字符串“41 42 43”是表示c#中的字节数组的好方法
var bytes = new byte[] { 0x41, 0x42, 0x43 };
but it is obviously not a good way to represent those 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(元数据);它将向您展示字符串(3)“ABC”。这是因为0x41 = 65 decimal = '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";
#9
0
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”字符串,就可以将其存储在数据库的二进制字段中。总之,这是谷歌给出的“php将字符串转换为二进制字符串”的第一个答案。这是我对这个问题的贡献。
The most voted answer by Francois Deschenes goes wrong for long strings (either bytestrings or bitstrings) that is because
弗朗索瓦•德舍内斯(Francois Deschenes)给出的最多人投票的答案在长字符串(bytestring或bitstring)中出错,这是因为
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.
base_convert()可能会由于使用的内部“double”或“float”类型相关的属性而对较大的数字失去精度。有关更具体的信息和限制,请参阅手册中的浮点数部分。
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”),您将无法在转换为bytestring时恢复原始位串。从bytestring转换回来,uyou将得到“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
#1
47
You want to use pack
and base_convert
.
您需要使用pack和base_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));
#2
26
Yes, sure!
是的,当然!
There...
在那里……
$bin = decbin(ord($char));
... and back again.
…和回来。
$char = chr(bindec($bin));
#3
9
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
, VARBINARY
or BLOB
columns.
如果希望在数据库中存储二进制数据,最常见的问题是数据库中的列定义。PHP不区分二进制数据和字符串,但是数据库可以。例如,在MySQL中,应该将二进制数据存储在二进制、VARBINARY或BLOB列中。
Another option would be to base64_encode
your PHP string and store it in some VARCHAR
or TEXT
column in the database. But be aware that the string's length will increase when base64_encode
is used.
另一个选项是对PHP字符串进行base64_encode并将其存储在数据库中的某个VARCHAR或文本列中。但是请注意,当使用base64_encode时,字符串的长度将会增加。
#4
3
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.
因为它是相同的。“转换”是多余的。
#5
3
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
#6
0
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
#7
0
I would most definitely recommend using the built in standard password libraries that come with PHP - Here is a good example on 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
#8
0
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 presenting that 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 present the byte array that in C# would be
如果您想要一个良好的人类可读的BLOB表示,那么显示它包含的字节是有意义的,并且可能使用十六进制而不是十进制。因此,字符串“41 42 43”是表示c#中的字节数组的好方法
var bytes = new byte[] { 0x41, 0x42, 0x43 };
but it is obviously not a good way to represent those 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(元数据);它将向您展示字符串(3)“ABC”。这是因为0x41 = 65 decimal = '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";
#9
0
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”字符串,就可以将其存储在数据库的二进制字段中。总之,这是谷歌给出的“php将字符串转换为二进制字符串”的第一个答案。这是我对这个问题的贡献。
The most voted answer by Francois Deschenes goes wrong for long strings (either bytestrings or bitstrings) that is because
弗朗索瓦•德舍内斯(Francois Deschenes)给出的最多人投票的答案在长字符串(bytestring或bitstring)中出错,这是因为
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.
base_convert()可能会由于使用的内部“double”或“float”类型相关的属性而对较大的数字失去精度。有关更具体的信息和限制,请参阅手册中的浮点数部分。
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”),您将无法在转换为bytestring时恢复原始位串。从bytestring转换回来,uyou将得到“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