Leb128 编码

<?php

// https://en.wikipedia.org/wiki/LEB128
// http://stackoverflow.com/questions/18195415/c-base128-function

class Leb128
{
    /**
     * Unsigned Encode
     *
     * @param integer $x
     * @return string
     */
    public static function uencode(int $x): string
    {
        if ($x < 0) {
            throw new \InvalidArgumentException("Value can't be < 0. Use sencode().", 10);
        }

        $str = '';
        do {
            $char = $x & 0x7f;
            $x >>= 7;
            if ($x > 0) {
                $char |= 0x80;
            }
            $str .= chr($char);
        } while ($x);

        return $str;
    }

    /**
     * Unsigned Decode
     *
     * @param string $str
     * @param integer $x
     * @param integer $maxlen
     * @return integer
     */
    public static function udecode(string $str, int &$x, int $maxlen = 16): int
    {
        $len = 0;
        $x = 0;
        while ($str) {
            $char = substr($str, 0, 1);
            $char = ord($char);
            $str = substr($str, 1);

            $x |= ($char & 0x7f) << (7 * $len);
            $len++;

            if (($char & 0x80) == 0) {
                break;
            }

            if ($len >= $maxlen) {
                throw new \RuntimeException(sprintf('Max length %d reached.', $maxlen), 20);
            }
        }
        return $len;
    }

    /**
     * Signed Encode
     *
     * @param integer $x
     * @return string
     */
    public static function sencode(int $x): string
    {
        $buf = '';
        $more = 1;
        //$negative = $x < 0;
        while ($more) {
            $char = $x & 0x7f;
            $x >>= 7;

            //if($negative){
            //    $intSize = 64;
            //    $x |= -(1 << ($intSize - 7));
            //}

            if (($x == 0 && ($char & 0x40) == 0) || ($x == -1 && ($char & 0x40))) {
                $more = 0;
            } else {
                $char |= 0x80;
            }
            $buf .= chr($char);
        }

        return $buf;
    }

    /**
     * Signed Decode
     *
     * @param string $str
     * @param integer $x
     * @param integer $maxlen
     * @param integer $intSize
     * @return integer
     */
    public static function sdecode(string $str, int &$x, int $maxlen = 16, int $intSize = 64): int
    {
        $len = 0;
        $x = 0;
        $char = 0;
        //$shift = 0;
        while ($str) {
            $char = substr($str, 0, 1);
            $char = ord($char);
            $str = substr($str, 1);

            $shift = 7 * $len;
            $x |= ($char & 0x7f) << $shift;
            $len++;

            if (($char & 0x80) == 0) {
                break;
            }

            if ($len >= $maxlen) {
                throw new \RuntimeException(sprintf('Max length %d reached.', $maxlen), 30);
            }
        }

        $shift = 7 * $len;

        // Sign bit of byte is 2nd high order bit (0x40)
        if ($shift < $intSize && ($char & 0x40)) {
            $x |= -(1 << $shift);
        }

        return $len;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哇哈哈苦的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值