programing

문자열을 이진으로 변환한 다음 PHP를 사용하여 다시 변환

stoneblock 2023. 8. 2. 08:40

문자열을 이진으로 변환한 다음 PHP를 사용하여 다시 변환

문자열을 이진으로 변환한 다음 표준 PHP 라이브러리에서 다시 변환할 수 있는 방법이 있습니까?

제가 하려는 일은 비밀번호를 데이터베이스에 저장하는 것입니다.먼저 해시함수를 사용하여 변환한 후에 바이너리로 저장하려고 합니다.


저는 이 기능을 사용하는 것이 가장 좋은 방법이라고 생각합니다.해시와 출력을 이진수로 동시에 수행하는 것 같습니다.

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

및 를 사용할 수 있습니다.

// 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));

네, 물론이죠!

저기...

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

그리고 다시 돌아옵니다.

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

문자열은 단지 바이트의 시퀀스이기 때문에 실제로는 PHP의 이진 데이터입니다.정확히 뭘 하려는 겁니까?

편집

이진 데이터를 데이터베이스에 저장하려면 데이터베이스의 열 정의가 문제가 되는 경우가 많습니다.PHP는 이진 데이터와 문자열을 구별하지 않지만 데이터베이스는 구별합니다.예를 들어 MySQL에서는 이진 데이터를 또는 열에 저장해야 합니다.

또 다른 옵션은 다음과 같습니다.base64_encode을 어떤 의신당 PHP 합니다.VARCHAR또는TEXT열을 선택합니다.그러나 문자열의 길이는 다음과 같이 증가합니다.base64_encode사용됩니다.

해시가 이미 이진 파일이며 데이터베이스에서 사용할 준비가 되었습니다.

그러나 데이터베이스 열 정의에서 예상하는 형식으로 변환해야 합니다.

PHP의 모든 문자열(5.3 이상까지)은 이진 문자열입니다.즉, 이진 데이터만 포함됩니다.

되었고, 은 그것을, 이 역사적인이며, 도 있지만 는 (이것그은유었고대다지, PHP 6코니결습했만못들뿐이니다입일사관심인적사역아도마는지머나답의은대로지되▁(ir▁php▁is▁(▁i이▁interest다뿐니입▁only▁answer▁but▁the▁php▁perhaps,▁6▁the▁never일▁stayed▁thethis▁has은▁it▁it사관심▁of인,적사▁same역▁work▁of▁still▁historic▁rest▁this▁made,▁6c도아마▁may는이지것 여전히 작동할 수 있지만 IIRC는b'string'제거되었거나 제거되지 않았습니다.

그러나 PHP 6과의 역호환성 때문에 문자열을 이미 바이너리로 명시적으로 캐스트할 수 있습니다.

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

그러나 이는 호환성을 위한 것일 뿐이며 코드에서 다음 작업을 수행할 수 있습니다.

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

똑같으니까요."변환"은 불필요합니다.

제가 찾은 가장 쉬운 방법은 문자열 대신 HEX로 변환하는 것이었습니다.효과가 있는 경우:

$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

PHP와 함께 제공되는 기본적표준 암호 라이브러리를 사용하는 것이 가장 좋습니다. 여기 사용 방법에 대한 좋은 예가 있습니다.


이진 문자열에서 소수점 이하로 이동하는 방법을 알고자 여기에 오신 분들을 위해 아래에 몇 가지 좋은 예가 있습니다.

이진 "문자열"을 십진수/문자로 변환하는 경우 다음과 같은 작업을 수행할 수 있습니다.

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";

위의 출력:

1
2
4
8
16
32
64
128
65
123452465

소수점 이하를 문자/문자열로 변환하는 경우 다음을 수행할 수 있습니다.

# 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";

위의 출력:

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

PHP의 문자열은 항상 BLOB입니다.따라서 문자열을 사용하여 데이터베이스 BLOB의 값을 유지할 수 있습니다.이 모든 것들은 BLOB를 제시하는 것과 관련이 있습니다.

사람이 읽을 수 있는 멋진 BLOB 표현을 원한다면 BLOB에 포함된 바이트를 표시하고 십진수 대신 십진수를 사용하는 것이 좋습니다.따라서 문자열 "41443"은 C#에서 다음과 같은 바이트 배열을 표시하는 좋은 방법입니다.

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

하지만 그것은 분명히 그 바이트들을 표현하는 좋은 방법이 아닙니다!문자열 "ABC"는 실제로 동일한 BLOB이기 때문에 효율적인 표현입니다(이 경우에만 그렇게 크지 않습니다).

실제로 일반적으로 해싱 함수와 같은 문자열을 반환하는 함수나 fread와 같은 다른 내장 함수에서 BLOB를 얻을 수 있습니다.

하드 코딩된 바이트로 문자열을 구성해야 하는 드문 경우(그러나 프로토타이핑을 시도할 때는 그리 드물지 않음) "16진수 문자열"을 PHP에서 종종 "2진수 문자열"로 부르는 것보다 더 효율적인 것은 없습니다.

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

네가 만약var_dump($data);당신에게 입니다.string(3) "ABC"그 이유는 0x41 = 65 소수 = 'A'(기본적으로 모든 인코딩에서)이기 때문입니다.

이진 데이터를 문자열로 해석하여 보는 것은 정확하게 직관적이지 않으므로 디버깅을 쉽게 하기 위해 기본 래퍼를 만드는 것이 좋습니다.가능한 한 가지 포장지는 다음과 같습니다.

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);
    }
}

이것은 제가 즉석에서 만든 것이고, 아마도 여러분만의 포장지를 만들기 위한 시작점일 것입니다.그러나 이 아이디어는 PHP에서 사용할 수 있는 가장 효율적인 구조이기 때문에 저장을 위해 문자열을 사용하는 동시에 내용을 검사하고 싶을 때 디버거 워치/평가에 사용할 수 있는 toArray()와 같은 방법을 제공하는 것입니다.

물론 당신은 이진 데이터에 문자열을 사용하는 것과 인터페이스할 때 완벽하게 간단한 PHP 배열을 대신 사용하고 문자열에 패킹할 수 있습니다.블럽을 실제로 수정하려는 정도에 따라 이 작업이 더 쉬울 수 있으며 공간 효율적이지는 않지만 많은 작업에 대해 허용 가능한 성능을 얻을 수 있다고 생각합니다.

기능을 설명하는 예:

// 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";

2021년에 여기에 있는 사람은 누구나 Steve Droz 답변을 사용할 수 있습니다. 하지만 안타깝게도, 그것은 한 캐릭터에 대해서만 가능합니다.그래서 저는 그것을 for 루프에 넣고 줄의 각 문자를 바꿉니다.

편집: 제가 만든 binary_encode 함수는 문자를 8비트로 변환하지 않고 (매우 중요한) 6-7비트로 변환하지만 운 좋게도 8비트로 만드는 데 필요한 추가 0만 추가하면 된다는 것을 깨달았습니다.아래 인코딩 기능을 업데이트했습니다.또한 디코드 기능은 프리펜드된 0과 없이 작동하기 때문에 수정할 필요가 없었습니다 :)

기능(업데이트):

function binary_encode($str){
    
    # Declare both Binary variable and Prepend variable
    $bin = (string)""; $prep = (string)"";
    
    # Iterate through each character of our input ($str) 
    for($i = 0; $i < strlen($str); $i++){
        
        # Encode The current character into binary
        $bincur = decbin( ord( $str[$i] ) );
        
        # Count the length of said binary
        $binlen = strlen( $bincur );
        
        # If the length of our character in binary is less than a byte (8 bits); Then
        # For how ever many characters it is short;
        # it will replace with 0's in our Prepend variable.
        if( $binlen < 8 ) for( $j = 8; $j > $binlen; $binlen++ ) $prep .= "0"; 
        
        # Build our correct 8 bit string and add it to our Binary variable
        $bin .= $prep.$bincur." ";
        
        # Clear our Prepend variable before the next Loop
        $prep = "";

    }

    # Return the final result minus the one whitespace at the end
    # (from our for loop where we build the 8 bit string
    return substr($bin, 0, strlen($bin) - 1);

}

function binary_decode($bin){
    $char = explode(' ', $bin);
    $nstr = '';
    foreach($char as $ch) $nstr .= chr(bindec($ch));
    return $nstr;
}

용도:

$bin = binary_encode("String Here");
$str = binary_decode("1010011 1110100 1110010 1101001 1101110 1100111 100000 1001000 1100101 1110010 1100101");

이전 라이브 데모:

http://sandbox.onlinephpfunctions.com/code/2553fc9e26c5148fddbb3486091d119aa59ae464

새 라이브 데모:

http://sandbox.onlinephpfunctions.com/code/1d71888cd41371646431f9914ccd86cf5ef6303e

문자열 비트 변환을 찾고 있었는데 여기에 왔습니다. 다음 케이스가 당신을 위한 것이라면 //그래서...만약 당신이 문자열에서 다른 비트로 비트를 사용하고 싶다면, 아마도 이 예가 도움이 될 것입니다.

$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

스테판 게릭의 대답이 실제로 옳은 답이라는 것은 정말 웃기는 일입니다.데이터베이스의 BINARY 필드에 저장하기 위해 문자열을 "011010101" 문자열로 변환할 필요는 없습니다.어쨌든 이것이 "php convert string to binary string"을 검색할 때 나오는 첫 번째 대답이기 때문입니다.여기 이 문제에 대한 저의 기여가 있습니다.

프랑수아 데슈네스가 가장 많이 투표한 답변은 긴 문자열(테스트 문자열 또는 비트 문자열)에 대해 잘못됩니다.

base_double은 사용된 내부 "double" 또는 "double" 유형과 관련된 속성으로 인해 큰 숫자에서 정밀도를 잃을 수 있습니다.자세한 내용 및 제한 사항은 설명서의 부동 소수점 번호 섹션을 참조하십시오.

보낸 사람: https://secure.php.net/manual/en/function.base-convert.php

이 제한을 해결하기 위해 입력 문자열을 청크로 자를 수 있습니다.아래 기능은 이 기술을 구현합니다.

<?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;

8의 배수가 아닌 비트 문자열(예: "101")을 삽입하면 테스트 문자열로 변환할 때 원래 비트 문자열을 복구할 수 없습니다.다시 변환하는 bytest 문자열에서 숫자적으로 동일하지만 문자열 길이가 다른 "00000101"을 얻을 수 있습니다.따라서 비트 문자열 길이가 중요한 경우 변환 후 문자열의 첫 번째 부분을 잘라내고 별도의 변수에 길이를 저장해야 합니다.

$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

변환에 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;

이것은 제가 여기서 찾은 자바스크립트 코드입니다: http://binarytotext.net/, 그들은 이 코드를 Vue.js와 함께 사용했습니다.코드에서 이 .aaa는 v-model 동적 값입니다.이진수를 텍스트 값으로 변환하기 위해 큰 숫자를 사용했습니다.추가 패키지를 설치하고 텍스트 필드로 다시 변환해야 합니다.제가 보기에, 그것은 쉬울 것 같아요.

언급URL : https://stackoverflow.com/questions/6382738/convert-string-to-binary-then-back-again-using-php