You are here

public static function ParagonIE_Sodium_Core_Util::hex2bin in Automatic Updates 8

Same name and namespace in other branches
  1. 7 vendor/paragonie/sodium_compat/src/Core/Util.php \ParagonIE_Sodium_Core_Util::hex2bin()

Convert a hexadecimal string into a binary string without cache-timing leaks

@internal You should not use this directly from another application

Parameters

string $hexString:

bool $strictPadding:

Return value

string (raw binary)

Throws

RangeException

TypeError

1 call to ParagonIE_Sodium_Core_Util::hex2bin()
ParagonIE_Sodium_Compat::hex2bin in vendor/paragonie/sodium_compat/src/Compat.php
Cache-timing-safe implementation of hex2bin().

File

vendor/paragonie/sodium_compat/src/Core/Util.php, line 301

Class

ParagonIE_Sodium_Core_Util
Class ParagonIE_Sodium_Core_Util

Code

public static function hex2bin($hexString, $strictPadding = false) {

  /* Type checks: */
  if (!is_string($hexString)) {
    throw new TypeError('Argument 1 must be a string, ' . gettype($hexString) . ' given.');
  }

  /** @var int $hex_pos */
  $hex_pos = 0;

  /** @var string $bin */
  $bin = '';

  /** @var int $c_acc */
  $c_acc = 0;

  /** @var int $hex_len */
  $hex_len = self::strlen($hexString);

  /** @var int $state */
  $state = 0;
  if (($hex_len & 1) !== 0) {
    if ($strictPadding) {
      throw new RangeException('Expected an even number of hexadecimal characters');
    }
    else {
      $hexString = '0' . $hexString;
      ++$hex_len;
    }
  }
  $chunk = unpack('C*', $hexString);
  while ($hex_pos < $hex_len) {
    ++$hex_pos;

    /** @var int $c */
    $c = $chunk[$hex_pos];

    /** @var int $c_num */
    $c_num = $c ^ 48;

    /** @var int $c_num0 */
    $c_num0 = $c_num - 10 >> 8;

    /** @var int $c_alpha */
    $c_alpha = ($c & ~32) - 55;

    /** @var int $c_alpha0 */
    $c_alpha0 = ($c_alpha - 10 ^ $c_alpha - 16) >> 8;
    if (($c_num0 | $c_alpha0) === 0) {
      throw new RangeException('hex2bin() only expects hexadecimal characters');
    }

    /** @var int $c_val */
    $c_val = $c_num0 & $c_num | $c_alpha & $c_alpha0;
    if ($state === 0) {
      $c_acc = $c_val * 16;
    }
    else {
      $bin .= pack('C', $c_acc | $c_val);
    }
    $state ^= 1;
  }
  return $bin;
}