/src/Pyrus/DER/BitString.php

https://github.com/CloCkWeRX/Pyrus · PHP · 109 lines · 77 code · 8 blank · 24 comment · 12 complexity · 9d8a2914d7fcbb23d8094dc26d6e9b89 MD5 · raw file

  1. <?php
  2. /**
  3. * \Pyrus\DER\BitString
  4. *
  5. * PHP version 5
  6. *
  7. * @category Pyrus
  8. * @package Pyrus
  9. * @author Greg Beaver <cellog@php.net>
  10. * @copyright 2010 The PEAR Group
  11. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  12. * @link https://github.com/pyrus/Pyrus
  13. */
  14. /**
  15. * Represents a Distinguished Encoding Rule Bit String
  16. *
  17. * @category Pyrus
  18. * @package Pyrus
  19. * @author Greg Beaver <cellog@php.net>
  20. * @copyright 2010 The PEAR Group
  21. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  22. * @link https://github.com/pyrus/Pyrus
  23. */
  24. namespace Pyrus\DER;
  25. class BitString extends \Pyrus\DER
  26. {
  27. const TAG = 0x03;
  28. protected $value = false;
  29. protected $bitcount = 0;
  30. function __construct($string = '', $bits = 0)
  31. {
  32. $this->setValue($string, $bits);
  33. }
  34. function setValue($string, $bits = 0)
  35. {
  36. if (is_string($string)) {
  37. if (preg_match('/[01]+/', $string)) {
  38. $this->value = $string;
  39. $this->bitcount = strlen($string);
  40. return;
  41. }
  42. }
  43. $string = decbin(intval($string));
  44. if (!$bits) {
  45. $bits = strlen($string);
  46. $extra = 8 - $bits % 8;
  47. if ($extra === 8) {
  48. $extra = 0;
  49. }
  50. $bits += $extra;
  51. $string = str_repeat('0', $extra) . $string;
  52. }
  53. if (strlen($string) < $bits) {
  54. $string = str_repeat('0', $bits - strlen($string));
  55. } elseif (strlen($string) < $bits) {
  56. $string = substr($string, strlen($string) - $bits);
  57. }
  58. $this->bitcount = $bits;
  59. $this->value = $string;
  60. }
  61. function serialize()
  62. {
  63. // pad the string with zeros
  64. $extra = 8 - strlen($this->value) % 8;
  65. if ($extra === 8) {
  66. $extra = 0;
  67. }
  68. $string = $this->value . str_repeat('0', $extra);
  69. $string = base_convert($string, 2, 16);
  70. if (strlen($string) % 2) {
  71. $string = '0' . $string;
  72. }
  73. $hexlen = strlen($string) / 2;
  74. $value = '';
  75. for ($i = 0; $i < $hexlen; $i++) {
  76. $byte = hexdec(substr($string, $i * 2, 2));
  77. $value .= chr($byte);
  78. }
  79. // note the number of padding bits applied
  80. $value = chr($extra) . $value;
  81. return $this->prependTLV($value, strlen($value));
  82. }
  83. function parse($data, $location)
  84. {
  85. $ret = parent::parse($data, $location);
  86. $unusedbits = ord($this->value[0]);
  87. $value = substr($this->value, 1);
  88. $str = '';
  89. $strlen = strlen($value);
  90. for ($i = 0; $i < $strlen; $i++) {
  91. if ($i == $strlen - 1) {
  92. $binary = substr(decbin(ord($value[$i])), 0, 8 - $unusedbits);
  93. } else {
  94. $binary = decbin(ord($value[$i]));
  95. }
  96. $str .= $binary;
  97. }
  98. $this->value = $str;
  99. return $ret;
  100. }
  101. }