【问题标题】:PHP convert string to hex and hex to stringPHP将字符串转换为十六进制和十六进制到字符串
【发布时间】:2020-11-07 01:41:44
【问题描述】:

我在 PHP 中这 2 种类型之间进行转换时遇到了问题。这是我在google中搜索到的代码

function strToHex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++){
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}


function hexToStr($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}

我查了一下,用异或加密的时候发现了。

我有字符串"this is the test",在与一个键进行异或后,我得到字符串↕↑↔§P↔§P ♫§T↕§↕ 的结果。之后,我尝试通过函数 strToHex() 将其转换为十六进制,我得到了这些12181d15501d15500e15541215712。然后,我用函数 hexToStr() 进行了测试,我得到了↕↑↔§P↔§P♫§T↕§q。那么,我应该怎么做才能解决这个问题呢?为什么我转换这2个样式值会出错?

【问题讨论】:

  • 你知道PHP中有hex2bin()bin2hex()吗?
  • strToHex 返回一个十六进制的 string - 所以如果你直接用 ^ 运算符对它进行异或,那不会给出任何好的结果.也许你可以给 strToHex 另一个参数是你想要异或的数字,并直接在该函数内部进行异或:$hex .= dechex(ord($string[$i]) ^ $MYKEYBYTE);
  • 我认为问题出在 hexToStr() 函数上。因为在转换成字符串的时候,会传递空格或者一些特殊字符,导致问题
  • 我试过 hex2bin() 和 bin2hex()。真的很好解决这个问题。但在实际情况下,它没有。如果我在用密钥对明文进行异或加密后调用 bin2hex() 函数,那就对了。但在实际情况中,我们通常在 XOR 之后使用 strToHex() ,所以当我们对 Crypt 与 KEY 进行异或解密得到明文时,调用 hexToStr() 会得到错误的结果。

标签: php string hex


【解决方案1】:

对于最终来到这里并且只是在寻找(二进制)字符串的十六进制表示的人。

bin2hex("that's all you need");
# 74686174277320616c6c20796f75206e656564

hex2bin('74686174277320616c6c20796f75206e656564');
# that's all you need

文档:bin2hexhex2bin

【讨论】:

【解决方案2】:

对于任何带有 ord($char)

这应该解决它:

<?php
function strToHex($string){
    $hex = '';
    for ($i=0; $i<strlen($string); $i++){
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
    return strToUpper($hex);
}
function hexToStr($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}


// Tests
header('Content-Type: text/plain');
function test($expected, $actual, $success) {
    if($expected !== $actual) {
        echo "Expected: '$expected'\n";
        echo "Actual:   '$actual'\n";
        echo "\n";
        $success = false;
    }
    return $success;
}

$success = true;
$success = test('00', strToHex(hexToStr('00')), $success);
$success = test('FF', strToHex(hexToStr('FF')), $success);
$success = test('000102FF', strToHex(hexToStr('000102FF')), $success);
$success = test('↕↑↔§P↔§P ♫§T↕§↕', hexToStr(strToHex('↕↑↔§P↔§P ♫§T↕§↕')), $success);

echo $success ? "Success" : "\nFailed";

【讨论】:

  • 在 strToHex 函数中,作为整个 dechex() 和 substr -2 的替代,可以只使用:$hex .= sprintf('%02.x', $ord);
  • 如果是16位怎么办?
【解决方案3】:

PHP:

字符串转十六进制:

implode(unpack("H*", $string));

十六进制转字符串:

pack("H*", $hex);

【讨论】:

  • 您可以通过使用list 来避免内爆调用,即:list(, $hex) = unpack('H*', $string);
  • 十六进制值 64 是 40。但它给我的回报是别的东西
【解决方案4】:

这是我使用的:

function strhex($string) {
  $hexstr = unpack('H*', $string);
  return array_shift($hexstr);
}

【讨论】:

【解决方案5】:
function hexToStr($hex){
    // Remove spaces if the hex string has spaces
    $hex = str_replace(' ', '', $hex);
    return hex2bin($hex);
}
// Test it 
$hex    = "53 44 43 30 30 32 30 30 30 31 37 33";
echo hexToStr($hex); // SDC002000173

/**
 * Test Hex To string with PHP UNIT
 * @param  string $value
 * @return 
 */
public function testHexToString()
{
    $string = 'SDC002000173';
    $hex    = "53 44 43 30 30 32 30 30 30 31 37 33";
    $result = hexToStr($hex);

    $this->assertEquals($result,$string);
}

【讨论】:

    【解决方案6】:

    使用@bill-shirley 回答并稍加补充

    function str_to_hex($string) {
    $hexstr = unpack('H*', $string);
    return array_shift($hexstr);
    }
    function hex_to_str($string) {
    return hex2bin("$string");
    }
    

    用法:

      $str = "Go placidly amidst the noise";
      $hexstr = str_to_hex($str);// 476f20706c616369646c7920616d6964737420746865206e6f697365
      $strstr = hex_to_str($str);// Go placidly amidst the noise
    

    【讨论】:

    • 为什么不先转换重音字符
    • 有什么特别推荐的方法吗? mb_convert_encoding?这超出了原来的范围,但是在没有解码功能的MSSQL中,十六进制信息会被转换回字符串。
    【解决方案7】:

    我只有一半的答案,但我希望它是有用的,因为它添加了 unicode (utf-8) 支持

    //decimal to unicode character
    function unichr($dec) { 
      if ($dec < 128) { 
        $utf = chr($dec); 
      } else if ($dec < 2048) { 
        $utf = chr(192 + (($dec - ($dec % 64)) / 64)); 
        $utf .= chr(128 + ($dec % 64)); 
      } else { 
        $utf = chr(224 + (($dec - ($dec % 4096)) / 4096)); 
        $utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64)); 
        $utf .= chr(128 + ($dec % 64)); 
      } 
      return $utf;
    }
    

    到字符串

    var_dump(unichr(hexdec('e641')));
    

    来源:http://www.php.net/manual/en/function.chr.php#Hcom55978

    【讨论】:

      【解决方案8】:

      您可以尝试以下代码将图像转换为十六进制字符串

      <?php
      $image = 'sample.bmp';
      $file = fopen($image, 'r') or die("Could not open $image");
      while ($file && !feof($file)){
      $chunk = fread($file, 1000000); # You can affect performance altering
      this number. YMMV.
      # This loop will be dog-slow, almost for sure...
      # You could snag two or three bytes and shift/add them,
      # but at 4 bytes, you violate the 7fffffff limit of dechex...
      # You could maybe write a better dechex that would accept multiple bytes
      # and use substr... Maybe.
      for ($byte = 0; $byte < strlen($chunk); $byte++)){
      echo dechex(ord($chunk[$byte]));
      }
      }
      ?>
      

      【讨论】:

        猜你喜欢
        • 2019-07-27
        • 2018-01-31
        • 1970-01-01
        • 2013-02-07
        • 2018-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多