当前位置: 首页 > news >正文

C++工程实战入门笔记6-函数(三)关于base16编码的原理和函数模块化实战

首先,理解为什么要编码?

计算机内部所有数据都是用二进制(0和1) 存储的。但二进制对人类来说很难阅读和理解。比如:

文本 "Hello" 在计算机中存储为:01001000 01100101 01101100 01101100 01101111

ASCII码

使用二进制表示所有的大写和小写字母,数字0 到9、标点符号,有固定对应表。

常见ASCII码的大小规则

数字< 大写字母 < 小写字母

1.数字比字母要小。如 “7”<“F”;
2.数字0比数字9要小,并按0到9顺序递增。如 “3”<“8” ;
3.字母A比字母Z要小,并按A到Z顺序递增。如“A”<“Z” ;
4.同个字母的大写字母比小写字母要小32。如“A”<“a” 。

几个常见字母的ASCII码大小: “A”为65;“a”为97;“0”为 48

在这里插入图片描述

base16编码

Unicode 码点从分配的那一刻起就是永久固定、不可改变的规则。
在这里插入图片描述
在这里插入图片描述
每个字符在Unicode标准中都有一个唯一的编号,称为"码点"。
Base16(十六进制编码)将每个字节(8位)的数据转换为两个十六进制字符(4位+4位),使用字符集 0123456789ABCDEF。
例如:

字符 'H' 的 ASCII 码是 72 (十六进制 0x48)
会被编码为 "48"

例如:

'A' → U+ 0041 → 十进制65'你' → U+ 4F60 → 十进制20320'😊' → U+ 1F60A → 十进制128522

根据码点值确定字节数

规则1:如果码点值 ≤ 127 (0x7F),使用1字节

包含所有ASCII字符:英文字母、数字、标点符号等

规则2:如果码点值 ≤ 2047 (0x7FF),使用2字节

包含拉丁字母扩展、希腊字母、西里尔字母、希伯来字母等

规则3:如果码点值 ≤ 65535 (0xFFFF),使用3字节

包含几乎所有常用汉字、日文、韩文字符基本多文种平面(BMP)中的所有字符

规则4:如果码点值 ≤ 1114111 (0x10FFFF),使用4字节

包含辅助平面字符:罕见汉字、历史文字、表情符号等

示例1:英文字母 ‘A’

Unicode码点: U+0041 (十进制65)
判断: 65127 → 使用1字节编码
UTF-8编码: 01000001 (0x41)

示例2:中文 ‘你’

Unicode码点: U+4F60 (十进制20320)
判断: 20320 > 2047? 是 → 2032065535? 是 → 使用3字节编码
UTF-8编码: 11100100 10111101 10100000 (0xE4 0xBD 0xA0)

示例3:表情符号 ‘😊’

Unicode码点: U+1F60A (十进制128522)  
判断: 128522 > 65535? 是 → 1285221114111? 是 → 使用4字节编码
UTF-8编码: 11110000 10011111 10011000 10001010 (0xF0 0x9F 0x98 0x8A)

编码规则

在这里插入图片描述
“你好”

先看“你”

”的码点:4F60,属于U+0800 - U+FFFF之间,需要三个字节。
4F60 转成二进制是

0100 1111 0110 0000

格式参考上图3字节,然后填入
在这里插入图片描述

11100100 10111101 10100000

再用十六进制表示上述码

E4 BD A0

再看“好”

”的码点:597D,属于U+0800 - U+FFFF之间,需要三个字节。
597D 转成二进制是

0101 1001 0111 1101

格式参考上图3字节,然后填入
在这里插入图片描述

11100101 10100101 10111101

再用十六进制表示上述码

E5 A5 BD

所以综上:“你好”的base16编码是:E4BDA0E5A5BD

base16编码和解码C++实现

无函数,直接实现

int main()
{SetConsoleOutputCP(65001); // 设置控制台输出编码为UTF-8//string test_str = "测试用于base16的字符串";string test_str = u8"你好";//base16编码string base16str;//unsigned char 和char的区别//8位一个字节//unsigned 无符号,在做算术运算时不管符号//char 第一位是符号位 二进制不能有正负号for (unsigned char c : test_str){char h = c >> 4 ;//取高位:移位丢弃低位 0100 0001 >>4 之后成为 0000 0100char l = c & 0b00001111;//取低位,与00001111做与操作 之后成为 0000 0001//cout << "h:"<<h << endl;//cout << "l:" << l << endl;base16str += base16_enc_tab[h];//0-15=>0-9,A-F//cout << base16str << endl;base16str += base16_enc_tab[l];//cout << base16str << endl;}//cout << base16str << endl;////base16解码string ostr;const vector<char> base16_dec_tab{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//0-9-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//10-19-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//20-29-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//30-39-1,-1,-1,-1,-1,-1,-1,-1,//40-470,1,2,3,4,5,6,7,8,9,//48-57-1,-1,-1,-1,-1,-1,-1,//58-6410,11,12,13,14,15//65-70 A-F};for (int i = 0; i < base16str.size(); i+=2){char ch = base16str[i];char cl = base16str[i + 1];//'A'=>10,'0'=>0 0-15 //65=>A=>10 48=>0 70=>Funsigned char h = base16_dec_tab[ch];unsigned char l = base16_dec_tab[cl];// h:0000 0100  l:0000 0001 ==> 0100 0001ostr += (h << 4 ) | l;}cout << ostr << endl;system("pause");
}*/

函数模块化实现

base16.h

#pragma once
#include<string>
#include<vector>///////////////////////////////////
//base16编码
//@para data:需要编码的二进制数据
//@return 返回base16编码的字符串
std::string Base16Encode(const std::vector<unsigned char> data);///////////////////////////////////
//base16解码
//@para str:需要解码的base16字符串,必须是2的倍数
//@return 返回原始的二进制数据
std::vector<unsigned char> Base16Decode(const std::string &str);

base16.cpp

#include "stdafx.h"
#include"base16.h"
#include<iostream>
using namespace std;//静态全局变量 作用域本cpp文件
static const string enc_tab = "0123456789ABCDEF";
static const vector<char> dec_tab{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//0-9-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//10-19-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//20-29-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,//30-39-1,-1,-1,-1,-1,-1,-1,-1,//40-470,1,2,3,4,5,6,7,8,9,//48-57-1,-1,-1,-1,-1,-1,-1,//58-6410,11,12,13,14,15//65-70 A-F
};///////////////////////////////////
//base16编码
//@para data:需要编码的二进制数据
//@return 返回base16编码的字符串
std::string Base16Encode(const std::vector<unsigned char> data)
{string res;for (unsigned char c : data){char h = c >> 4;//取高位:移位丢弃低位 0100 0001 >>4 之后成为 0000 0100char l = c & 0b00001111;//取低位,与00001111做与操作 之后成为 0000 0001res += enc_tab[h];//0-15=>0-9,A-Fres += enc_tab[l];}return res;
}///////////////////////////////////
//base16解码
//@para str:需要解码的base16字符串,必须是2的倍数
//@return 返回原始的二进制数据
std::vector<unsigned char> Base16Decode(const std::string &str)
{if (str.size() % 2 != 0){cerr << "base16 string is error" << endl;return{};}std::vector<unsigned char> res;for (int i = 0; i < str.size(); i += 2){char ch = str[i];char cl = str[i + 1];//'A'=>10,'0'=>0 0-15 //65=>A=>10 48=>0 70=>Funsigned char h = dec_tab[ch];unsigned char l = dec_tab[cl];// h:0000 0100  l:0000 0001 ==> 0100 0001res.push_back( (h << 4) | l);}return res;
}

主函数

#include "stdafx.h"
#include<iostream>
#include<bitset>
#include<string>
#include<vector>
#include "base16.h"
#include <windows.h>
using namespace std;
//编码用的映射表
//const string base16_enc_tab = "0123456789ABCDEF";
int main()
{SetConsoleOutputCP(65001);string test_str = u8"这个世界会好吗?";cout << u8"原文:" << test_str << endl;cout << endl;vector<unsigned char> data(test_str.begin(), test_str.end());data.push_back('\0');auto  base16_str = Base16Encode(data);cout << u8"编码后base16:" << base16_str << endl;cout << endl;auto dec_str =  Base16Decode(base16_str);cout << u8"base16解码后:" << dec_str.data() << endl;cout << endl;system("pause");
}
http://www.dtcms.com/a/353410.html

相关文章:

  • LINUX --- 网络编程(二)
  • OpenAi在中国拿下“GPT”商标初审!
  • October 2019 Twice SQL Injection
  • Qt图片上传系统的设计与实现:从客户端到服务器的完整方案
  • 对比视频处理单元(VPU)、图形处理器(GPU)与中央处理器(CPU)
  • 多模态模型如何处理和理解图片
  • PPT处理控件Aspose.Slides教程:在.NET中开发SVG到EMF的转换器
  • STM32学习日记
  • 替身演员的艺术:pytest-mock 从入门到飙戏
  • Java基础 8.27
  • 如何使用windows实现与iphone的隔空投送(AirDrop)
  • 【Docker基础】Docker-compose数据持久化与卷管理:深入解析docker volume命令集
  • 【重学MySQL】八十九、窗口函数的分类和使用
  • Mysql杂志(三)
  • 【46页PPT】公司数字化转型规划与实践(附下载方式)
  • 学习Python中Selenium模块的基本用法(7:元素操作-1)
  • 应变片与分布式光纤传感:核心差异与选型指南
  • 极海发布APM32F425/427系列高性能MCU:助力工业应用升级
  • laravel学习并连接mysql数据库
  • Linux 软件编程(十二)网络编程:TCP 并发服务器构建与 IO 多路复用
  • redis---set详解
  • Tortoisegit配置ssh教程
  • Vue3 新特性 defineModel 全面解析:让 v-model 写法更优雅
  • 项目智能家居---OrangePi全志H616
  • GitHub 宕机自救指南:保障开发工作连续性
  • 蓝桥杯算法之基础知识(3)——Python的idle的快捷键设置(idle改键)
  • 信任,AI+或人机环境系统智能的纽带
  • 深入解析EDCA通道与参数配置:优化Wi-Fi服务质量的关键策略
  • 新手向:网络编程完全指南
  • Jetson 分区知识全解与 OTA 升级实战