美文网首页
PHP 实现 base64 编码

PHP 实现 base64 编码

作者: 过往云技 | 来源:发表于2019-04-25 14:27 被阅读0次

Base64 是一种基于64个可打印字符来表示二进制数据的表示方法,编码后的数据比原始数据略长,为原来的 4/3。编码表由64 个字符组成:26个大写英文字母 + 26个小写英语字母 + 数字0-9 + 符号 "+" + 符号 "/",其 ASCII 值为 0-63

编码过程:

 1、每 3 个字节组成一组,(3*8)组成一串24个进制位;例:111001101001010110001111
 2、将 24 个进制位分 4 组,每组 6 个进制位,在前补 00 扩展成 32 个进制位 = 4 个字节;例:00111001 00101001 00010110 00001111
 3、将每个字节转十进制,匹配编码表对应字符,组成新的 4 个字符

Base64 编码表

image.png

满足 3 个字节情况下(utf-8 字符集一个中文字符等于 3 个字节)

原文本 Min 经过 base64 编码后等到新字符 TWlu

image.png

不满足 3 个字节,2 个字节情况下,在编码后的字符末尾填充1个 = 号

原文本 Mi 经过 base64 编码后等到新字符 TWk=

image.png

不满足 3 个字节,1 个字节情况下,在编码后的字符末尾填充 2 个 = 号

原文本 M 经过 base64 编码后等到新字符 TQ==

image.png
utf-8 中文字符『敏』,其对应的16进制是 E6958F,转换二进制为:111001101001010110001111 占三个字节
image.png

代码

<?php


namespace Patterns\Algorithm;


class Base64
{
    private $_encode_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    private $_strpad = ['==', '=', ''];

    /**
     * 输入字符以3个字节分组,3 个字节 = base64 4个字节
     * 3个字节为一组
     * * 第一个字符 = 输入第一个字符右移 2 位
     * * 第二个字符 = 输入第一个字符左移 4 位 + 输入第二个字符右移 4 位
     * * 第三个字符 = 输入第一个字符左移 2 位 + 输入第三个字符右移 6 位
     * * 第四个字符 = 取输入第三个字符右 6 位
     * base64 编码
     * @param string $str
     * @return string
     */
    public function encodebit(string $str):string
    {
        $strLen = strlen($str);
        $subIndex = 0;
        $subStr = $out = '';

        while ($strLen > 2){
            $subStr = substr($str, $subIndex, 3);
            $fir = ord($subStr[0]) >> 2;
            $sc = ((ord($subStr[0]) & 3) << 4) + ((ord($subStr[1])) >> 4);
            $th = ((ord($subStr[1]) & 15) << 2) + (ord($subStr[2]) >> 6);
            $end = ord($subStr[2]) & 63;

            $out .= $this->_encode_table[$fir];
            $out .= $this->_encode_table[$sc];
            $out .= $this->_encode_table[$th];
            $out .= $this->_encode_table[$end];

            $subIndex += 3;
            $strLen -= 3;
        }

        if(0 === $strLen){
            return $out;
        }

        $str = substr($str, $subIndex);
        $out .= $this->_encode_table[ord($str[0]) >> 2];

        if($strLen > 1){
            $out .= $this->_encode_table[((ord($str[0]) & 3) << 4) + (ord($str[1]) >> 4)];
            $out .= $this->_encode_table[(ord($str[1]) & 15) << 2];
            $out .= '=';
        } else {
            $out .= $this->_encode_table[(ord($str[0]) & 3) << 4];
            $out .= '==';
        }

        return $out;
    }

    /**
     * 编码
     * base64 将 3 个字节转成 4 个字节
     *  每 3 个字节组成一组,(3*8)组成一串24个进制位
     *  将 24 个进制位分 4 组,每组 6 个进制位,在前补 00 扩展成 32 个进制位 = 4 个字节
     *  将每个字节转十进制,匹配编码表对应字符,组成新的 4 个字符
     *
     * 不足 3 个字节情况:
     *  2 个字节:按照上述步骤可组成新的 3 个字符,在末尾补充 1 个 = 号,即 xxx=
     *  1 个字节:按照上述步骤可组成新的 2 个字符,在末尾补充 2 个 = 号,即 xx==
     * @param string $data
     * @return string
     */
    public function encode(string $data):string
    {
        $strLen = strlen($data);
        $subIndex = 0;
        $out = '';

        $offset = ceil($strLen / 3);
        for($i = 0; $i < $offset; $i++){
            $binstr = '';
            $subStr = substr($data, $subIndex, 3);
            $strLen = strlen($subStr);
            for($k = 0; $k < $strLen; $k++){
                $decbin = decbin(ord($subStr[$k]));
                $binstr .= str_pad($decbin, 8, 0, STR_PAD_LEFT);
            }

            $out .= $this->bintoChar($strLen, $binstr);

            $subIndex += 3;
        }

        $out .= $this->_strpad[$strLen - 1];

        return $out;
    }

    /**
     * 将8位二进制组成的进制位进行分组,6 位一组:每组在前方增 00 填充成 8 位,不足8位则在后方补 0
     * @param int $strSize
     * @param string $bin
     * @return string
     */
    private function bintoChar(int $strSize, string $bin):string
    {
        $subIndex = 0;
        $char = '';

        while ($strSize >= 0){
            $substr = '00' . substr($bin, $subIndex, 6);
            $substr = str_pad($substr, 8, 0, STR_PAD_RIGHT);
            $char .= $this->_encode_table[bindec($substr)];

            $subIndex += 6;
            $strSize--;
        }

        return $char;
    }
}

$base64 = new Base64();

$str = 'test';

echo 'base: ' . base64_encode($str),PHP_EOL;

echo 'base: ' . $base64->encodebit($str). PHP_EOL;

echo 'base: ' . $base64->encode($str) . PHP_EOL;

相关文章

  • php实现base64编码

    作用 有一些字符是无法直接显示,或者显示成看不懂的多字节字符,或者显示成乱码的。比如说 ASCII 表里的大半字符...

  • PHP 实现 base64 编码

    Base64 是一种基于64个可打印字符来表示二进制数据的表示方法,编码后的数据比原始数据略长,为原来的 4/3。...

  • Base64

    Base64简介 Base64 原理解析 编码实现 Base64简介 命令行运行base64编码和解码 对文件操作...

  • 编码与加密

    一、阅读基础 1、基础 一、Base64编码与解码 2、原理 4、代码实现 Base64编码 Base64解码 二...

  • CryptoJS 使用

    数组加密,Utf8编码,传递,加解密 加密,Base64编码,传递,解密 引用PHP 和 Web 端对称加密传输|...

  • Base64 之 JavaScript 实现

    相关文章:一步到位 Base64 编码在Web前端还可以这样实现Base64 JavaScript 实现 Base...

  • base64 编码原理

    近期接触AI图片识别,图片转码,从而接触到base64编码原理。为后续实现此编码原理,先学习了解~ base64编...

  • iOS URL安全的Base64编码、解码

    参考iOS开发探索-Base64编码iOS URL编码&base64编码URL安全的Base64编码,解码 为什么...

  • BASE64 编码简析

    Base64编码: <1>·Base64编码简介: <2>·使用Base64的原因: <3>·编码原理: 成这个字...

  • SMTP整理

    账号:BASE64编码的账号 密码:BASE64编码的密码 快速BASE64编码网址: http://tools....

网友评论

      本文标题:PHP 实现 base64 编码

      本文链接:https://www.haomeiwen.com/subject/mzzbgqtx.html