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

培训教育类网站模板营销策划与运营

培训教育类网站模板,营销策划与运营,中国人在线观看免费高清,网站制作源码版权一、ASN.1 是什么? ASN.1(Abstract Syntax Notation One),中文名称为抽象语法记法一,是一种描述数据结构与编码规则的国际标准,是一种对数据进行表示、编码、传输和解码的数据格式。数字1被ISO加在ASN的后…

一、ASN.1 是什么?

ASN.1(Abstract Syntax Notation One),中文名称为抽象语法记法一,是一种描述数据结构与编码规则的国际标准,是一种对数据进行表示、编码、传输和解码的数据格式。数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为ASN.2等,但截止到2026年也仅仅到1。

ASN.1是一种独立于硬件和编程语言的数据描述语言,由ISO和ITU-T联合制定。它的核心目标是解决异构系统间的数据兼容性问题,其核心价值:

  • 平台无关性:独立于硬件架构和编程语言
  • 双向能力:既能描述数据结构,也能定义编码规则
  • 广泛应用:X.509证书、SNMP、5G NAS协议、LDAP等
应用数据
ASN.1抽象语法
编码规则
BER: 基本编码规则
DER: 规范编码规则
PER: 紧凑编码规则
二进制传输

最常见的包括基本编码规则(BER)、正则编码规则(CER)和非典型编码规则(DER):

ASN.1描述
BER编码
DER编码
PER编码
抽象数据结构
传输语法
二进制流

二、编码规范

1. 数据类型分类

数据类型描述ASN.1定义语法编码规则(标签和结构)
基本类型
INTEGER整数INTEGER标签 0x02(基本类型),BER编码为不定长整数。
BOOLEAN布尔值BOOLEAN标签 0x01,值为 0(false)或 0xFF(true)。
BIT STRING位字符串BIT STRING标签 0x03,包含位数和字节数据。
OCTET STRING字节字符串OCTET STRING标签 0x04,直接存储字节。
NULL空值NULL标签 0x05,长度为 0
OBJECT IDENTIFIER对象标识符OBJECT IDENTIFIER标签 0x06,编码为区分编码规则(DER)。
REAL浮点数REAL标签 0x09,支持多种格式(如十进制、十六进制)。
ENUMERATED枚举类型ENUMERATED { value1, value2, ... }标签 0x0A,编码方式与 INTEGER 相同。
字符字符串类型
UTF8StringUTF-8编码字符串UTF8String标签 0x0C(Universal 12.04),存储UTF-8字节。
PrintableString可打印字符(ASCII 32-126)PrintableString标签 0x13(Universal 19)。
IA5StringASCII字符串IA5String标签 0x16(Universal 22)。
NumericString数字和空格(0-9, 空格)NumericString标签 0x12(Universal 18)。
VisibleString可见ASCII字符(32-126)VisibleString标签 0x26(Universal 26)。
GeneralString扩展ASCII(ISO 8859-1)GeneralString标签 0x27(Universal 27)。
UniversalStringUnicode UCS-4UniversalString标签 0x28(Universal 28)。
BMPStringUnicode UCS-2BMPString标签 0x30(Universal 30)。
时间类型
UTCTimeUTC时间(格式:YYMMDDHHMMSSZ)UTCTime标签 0x17(Universal 23)。
GeneralizedTime扩展时间格式(如:YYYYMMDDHHMMSSZ)GeneralizedTime标签 0x18(Universal 24)。
构造类型
SEQUENCE序列结构(按顺序编码元素)SEQUENCE { ... }标签 0x30(构造类型,0x16 + 构造标识),元素按顺序编码。
SET集合结构(元素按特定顺序编码)SET { ... }标签 0x31(构造类型,0x17 + 构造标识),元素按字典序排列。
CHOICE选择类型(从多个类型中选一个)CHOICE { ... }根据选中的类型编码,标签由选中类型决定。
ANY任意类型(直接传递原始编码)ANY标签 0x00(Universal 00),直接传递原始编码。
EXTERNAL外部数据(包含编码标识和数据)EXTERNAL { ... }标签 0x0C(Universal 8,构造类型),包含编码标识和数据。
INSTANCE OF实例类型(根据实例类型编码)INSTANCE OF Type根据实例类型编码,标签由实例类型决定。
OPEN TYPE开放类型(通常与CHOICE或SEQUENCE结合使用)[0] IMPLICIT Type通过类型标识符动态确定编码方式。

说明

  • 标签值:所有标签均为十六进制表示,属于通用类(Universal Class)。
  • 构造类型:标签值为基本标签(如 0x16 对应 SEQUENCE)加上构造标识位 0x20,例如 SEQUENCE 的编码标签为 0x300x16 | 0x20)。
  • 编码规则:BER(基本编码规则)、CER(规范编码规则)、DER(确定编码规则)的标签一致,但编码结构可能不同(如 SET 在 DER 中要求元素按字典序排列)。
  • 扩展类型:如 SEQUENCE OFSET OF 是构造类型的扩展形式,标签与 SEQUENCESET 相同。

此表格覆盖了ASN.1的主要数据类型及其编码规则,适用于大多数应用场景。

2. 编码规则家族

40% 30% 10% 15% 5% ASN.1编码规则市场份额 BER DER CER PER 其他
  • BER(Basic Encoding Rules):最基础的TLV编码(Tag-Length-Value)
  • DER(Distinguished Encoding Rules):BER的子集,保证唯一编码形式(用于数字证书)
  • PER(Packed Encoding Rules):针对带宽敏感场景的紧凑编码

三、核心编码规则

1. BER(基本编码规则)

采用TLV(Type-Length-Value)三元组结构:

+----------+----------+-----------------+
| 类型标签 | 长度字段 | 值字段          |
| (1字节)  | (1-n字节)| (变长)          |
+----------+----------+-----------------+

2. DER(可辨别编码规则)

BER的子集,增加约束:

  • 长度字段必须使用确定形式
  • 布尔值必须用0xFF
  • 集合元素按标签排序

3. PER(压缩编码规则)

删除TLV元数据,极致压缩:

+-----------------------+
| 纯数据值(无标签信息) |
+-----------------------+

4.实战演示:X.509证书片段解析

我们解析一个X.509证书的片段:30 0D 02 01 0A 01 01 FF 02 01 0B

30 0D - SEQUENCE
02 01 0A - INTEGER 10
01 01 FF - BOOLEAN TRUE
02 01 0B - INTEGER 11

对应ASN.1定义:

CertFragment ::= SEQUENCE {version    INTEGER,  -- 值=10isValid    BOOLEAN,  -- 值=TRUEserial     INTEGER   -- 值=11
}

四、C++实现ANS.1编码解析

需求内容: 解析以下ASN.1的字符串:

3077021f321171f81a5e0b5b6348549365b60691889e8499e21509634f2cf8e73626b20220611a1f010df10f999ffdfd24b9b458865919ff10d12c77547f74c7f7b5efed7e042078b6643339ba91202a0e005929f9162afa087b78db422f44a09c352bc30dc2cc04101ae5aacfe295350a42b96aa111ffcb94

1.定义TLV结构体

// ======================================
// ASN.1 节点结构体
// ======================================
struct ASN1Node
{unsigned char tag;                  // 节点类型标识unsigned int length;                // 数据长度(字节)std::vector<unsigned char> value;   // 原始数据值
};

2.定义解析后的序列结构

// ======================================
// ASN.1 解析结果结构体
// ======================================
struct ParsedSequence
{std::vector<ASN1Node> children;     // 序列中的子节点
};

3.解析以下ASN.1串

#include <cctype>
#include <cstdint>
#include <stdexcept>
#include <cctype>
#include <cstddef>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>// ======================================
// ASN.1 节点结构体
// ======================================
struct ASN1Node
{unsigned char tag;                  // 节点类型标识unsigned int length;                // 数据长度(字节)std::vector<unsigned char> value;   // 原始数据值
};// ======================================
// ASN.1 解析结果结构体
// ======================================
struct ParsedSequence
{std::vector<ASN1Node> children;     // 序列中的子节点
};// ======================================
// 辅助函数:将十六进制字符转换为字节
// ======================================
static unsigned char HexCharToByte(char c)
{if (c >= '0' && c <= '9')return static_cast<unsigned char>(c - '0');if (c >= 'a' && c <= 'f')return static_cast<unsigned char>(c - 'a' + 10);if (c >= 'A' && c <= 'F')return static_cast<unsigned char>(c - 'A' + 10);// 防御:无效输入立即终止throw std::invalid_argument("无效十六进制字符: " + std::string(1, c));
}// ======================================
// 核心函数:十六进制字符串转字节数组
// 符合规范 2.1:显式初始化变量
// 符合规范 3.1:严格边界检查
// ======================================
static std::vector<unsigned char> HexStringToBytes(const std::string& hexStr)
{if (hexStr.length() % 2 != 0){throw std::invalid_argument("十六进制字符串长度必须为偶数");}std::vector<unsigned char> result;result.reserve(hexStr.size() / 2);// 安全处理:逐对字节转换for (size_t i = 0; i < hexStr.length(); i += 2){try{unsigned char highNibble = HexCharToByte(hexStr[i]);unsigned char lowNibble = HexCharToByte(hexStr[i + 1]);result.push_back(static_cast<unsigned char>((highNibble << 4) | lowNibble));}catch (const std::invalid_argument& e){throw std::invalid_argument("位置 " + std::to_string(i) + ": " + e.what());}}return result;
}// ======================================
// 核心函数:解析长度字段(含长格式支持)
// 符合规范 5.5.1:资源操作防御性编程
// ======================================
static unsigned int ParseASN1Length(const std::vector<unsigned char>& data, size_t& currentIndex)
{// 前置条件校验(强制防御编程)if (currentIndex >= data.size()){throw std::out_of_range("索引越界: index=" +std::to_string(currentIndex) +", size=" +std::to_string(data.size()));}unsigned char firstByte = data[currentIndex++];// 处理短格式长度if (firstByte < 0x80){return static_cast<unsigned int>(firstByte);}// 处理长格式长度unsigned int lengthBytes = firstByte & 0x7F;// 长度域防护:防止恶意超长if (lengthBytes > 4){throw std::runtime_error("ASN.1长度字段超过4字节限制: " +std::to_string(lengthBytes));}// 边界检查:确保数据足够if (currentIndex + lengthBytes > data.size()){throw std::out_of_range("长格式长度字段越界: position=" +std::to_string(currentIndex) +", requiredBytes=" +std::to_string(lengthBytes));}unsigned int calculatedLength = 0;for (unsigned int i = 0; i < lengthBytes; ++i){calculatedLength = (calculatedLength << 8) |data[currentIndex++];}// 二次验证:计算结果有效性if (calculatedLength == 0){throw std::logic_error("ASN.1长度不能为零(长格式)");}return calculatedLength;
}// ======================================
// 核心函数:解析单个ASN.1 TLV节点
// 符合规范 3.2:分层异常捕获机制
// 符合规范 4.7:完整记录异常上下文
// ======================================
static ASN1Node ParseTLVNode(const std::vector<unsigned char>& data, size_t& currentIndex
)
{ASN1Node node;// 边界防护if (currentIndex >= data.size()){throw std::out_of_range("TLV解析起始位置越界");}// 1. 读取TAGnode.tag = data[currentIndex++];// 2. 读取长度(自动处理长格式)node.length = ParseASN1Length(data, currentIndex);// 3. 校验值域边界if (currentIndex + node.length > data.size()){throw std::out_of_range("值字段越界: 预期长度=" +std::to_string(node.length) +", 剩余字节=" +std::to_string(data.size() - currentIndex));}// 4. 安全拷贝值数据node.value.resize(node.length);for (size_t i = 0; i < node.length; ++i){node.value[i] = data[currentIndex + i];}currentIndex += node.length;  // 更新索引位置return node;
}// ======================================
// 主解析函数:处理SEQUENCE和子节点
// 符合规范 2.5:单一职责原则
// ======================================
static ParsedSequence ParseASN1Sequence(const std::vector<unsigned char>& bytes)
{size_t index = 0;ParsedSequence result;// 1. 解析顶层SEQUENCEASN1Node sequenceNode = ParseTLVNode(bytes, index);// 强类型校验if (sequenceNode.tag != 0x30){throw std::runtime_error("根元素必须为SEQUENCE(0x30),实际为: 0x" +(std::ostringstream{} << std::hex << static_cast<int>(sequenceNode.tag)).str());}// 2. 序列内部解析状态size_t innerIndex = 0;const std::vector<unsigned char>& innerData = sequenceNode.value;// 3. 解析四个子元素for (int expectedCount = 0; expectedCount < 4; ++expectedCount){if (innerIndex >= innerData.size()){throw std::runtime_error("元素数量不足: 预期4个,实际" +std::to_string(result.children.size()));}ASN1Node child = ParseTLVNode(innerData, innerIndex);// 标签合法性校验 (INTEGER/OCTET_STRING)if ((expectedCount < 2 && child.tag != 0x02) ||(expectedCount >= 2 && child.tag != 0x04)){std::string expectedType =(expectedCount < 2) ? "INTEGER(0x02)" : "OCTET_STRING(0x04)";throw std::runtime_error("位置[" + std::to_string(expectedCount) +"]应是" + expectedType +", 实际标签: 0x" +(std::ostringstream{} << std::hex << static_cast<int>(child.tag)).str());}result.children.push_back(child);}// 4. 尾部数据防护if (innerIndex != innerData.size()){throw std::runtime_error("序列尾部存在冗余数据: " +std::to_string(innerData.size() - innerIndex) + "字节");}// 5. 最后验证元素数量if (result.children.size() != 4){throw std::logic_error("解析逻辑错误:元素计数不一致");}return result;
}// ======================================
// 格式化输出函数(符合XML风格)
// 符合规范 8.3:中文注释及结构化文档
// ======================================
static std::string FormatXMLOutput(const ParsedSequence& sequence)
{std::ostringstream xmlStream;xmlStream << "<SEQUENCE>\n";for (size_t i = 0; i < sequence.children.size(); ++i){const ASN1Node& node = sequence.children[i];std::string tagName;// 确定标签名称(强类型匹配)switch (node.tag){case 0x02: tagName = "INTEGER"; break;case 0x04: tagName = "OCTET_STRING"; break;default:// 防御性处理(逻辑应确保不会执行)throw std::logic_error("内部错误:未知节点类型");}// 将二进制值转为大写的十六进制字符串xmlStream << "  <" << tagName << ">0x";xmlStream << std::hex << std::uppercase << std::setfill('0');for (const auto& byte : node.value){xmlStream << std::setw(2) << static_cast<unsigned int>(byte);}xmlStream << "</" << tagName << ">\n";}xmlStream << "</SEQUENCE>";return xmlStream.str();
}// ======================================
// 函数: ASN1Dump
// 功能: 将ParsedSequence对象转成格式化字符串列表
// 输入: seq - 解析后的ASN1序列对象
// 输出: 包含所有子节点格式信息的字符串列表
// 规范: 
//   1. 每个子节点单独一行
//   2. 每行三个元素空格分隔: 
//       当前节点类型 节点长度(十进制) 值(十六进制大写)
//   3. 值数据不带0x前缀
// ======================================
std::vector<std::string> ASN1Dump(const ParsedSequence& seq)
{// 结果容器预分配空间std::vector<std::string> dumpResult;dumpResult.reserve(seq.children.size());// 遍历所有子节点for (const ASN1Node& node : seq.children){// 元素1: 根据ASN.1标签标识获取类型名称std::string typeName;switch (node.tag){case 0x02: typeName = "INTEGER"; break;case 0x04: typeName = "OCTET_STRING"; break;case 0x30: typeName = "SEQUENCE"; break;case 0x03: typeName = "BIT_STRING"; break;case 0x06: typeName = "OBJECT_ID"; break;default:    // 防御性处理未知类型std::ostringstream hexTag;hexTag << "UNKNOWN_0x"<< std::hex << std::uppercase<< std::setw(2) << std::setfill('0')<< static_cast<int>(node.tag);typeName = hexTag.str();}// 元素2: 十进制长度const std::string lengthStr = std::to_string(node.length);// 元素3: 十六进制值字符串(不带0x前缀)std::ostringstream hexStr;hexStr << std::hex << std::uppercase << std::setfill('0');for (const unsigned char byte : node.value){hexStr << std::setw(2) << static_cast<int>(byte);}// 组装单行格式std::ostringstream line;line << typeName << " " << lengthStr << " " << hexStr.str();dumpResult.push_back(line.str());}return dumpResult;
}// ======================================
// 公开接口函数(符合规范8.5)
// ======================================
std::string ParseASN1HexString(const std::string& hexInput)
{try{// 保障性检查:输入完整性if (hexInput.empty()){throw std::invalid_argument("输入字符串为空");}// 严格转换HEX数据(包含验证)std::vector<unsigned char> bytes = HexStringToBytes(hexInput);// 核心解析过程ParsedSequence parsed = ParseASN1Sequence(bytes);// 格式化输出auto result = ASN1Dump(parsed);// 组合结果std::string output;for (auto& v : result){output += v + "\n";}return output;}catch (const std::exception& e){// 结构化错误处理(符合规范4.9)throw std::runtime_error(std::string("ASN1解析失败: ") + e.what() +"\n输入数据: " + hexInput);}
}

4.代码测试

int main()
{std::string ans1_text = "3077021f321171f81a5e0b5b6348549365b60691889e8499e21509634f2cf8e73626b20220611a1f010df10f999ffdfd24b9b458865919ff10d12c77547f74c7f7b5efed7e042078b6643339ba91202a0e005929f9162afa087b78db422f44a09c352bc30dc2cc04101ae5aacfe295350a42b96aa111ffcb94";auto rst = ParseASN1HexString(ans1_text);std::cout << "result:\n" << rst << std::endl;return 0;
}

测试结果:

result:
INTEGER 31 321171F81A5E0B5B6348549365B60691889E8499E21509634F2CF8E73626B2
INTEGER 32 611A1F010DF10F999FFDFD24B9B458865919FF10D12C77547F74C7F7B5EFED7E
OCTET_STRING 32 78B6643339BA91202A0E005929F9162AFA087B78DB422F44A09C352BC30DC2CC
OCTET_STRING 16 1AE5AACFE295350A42B96AA111FFCB94
http://www.dtcms.com/wzjs/84028.html

相关文章:

  • 南江县住房和城乡建设局网站做谷歌推广比较好的公司
  • 网站开发方案目录aso安卓优化
  • 深圳营销型网站建设服务网站定制
  • 厦门公司做网站在线一键生成网页
  • 做网站最好的软件是外贸如何推广
  • wordpress 论坛功能天津seo排名
  • 长治网站建设网络营销常见术语
  • 网站建设事宜排行榜百度
  • 网站上怎么做动画广告seo81
  • 瑞安学校网站建设互联网销售怎么做
  • wordpress加超链接关键词优化案例
  • 沙元浦做网站的公司龙岗网站设计
  • 广州手机建设网站苏州百度
  • wordpress主题 tob长春seo招聘
  • 网站技术架构图千度seo
  • html制作手机网站seo网站优化工具
  • 荆门网站建设贵港seo关键词整站优化
  • 二手车网站开发PPT免费发布信息的平台有哪些
  • 保险做的好的网站有哪些内容seo整站优化更能准确获得客户
  • 贵州网站制作设计公司哪家好推广普通话的意义论文
  • wordpress开启多站点后台没显示关键字排名优化工具
  • 网站h1标签怎么做google谷歌搜索引擎入口
  • 武汉网上推广的网站百度人工客服电话多少
  • 去视频网站做编辑百度收录规则
  • 新纪实网站建设搜索引擎营销的案例
  • 美国cn2站群服务器饥饿营销案例
  • 庄河网站建设公司广告投放渠道
  • 域名备案查询网站备案seo创业
  • 无锡做网络推广的公司百度seo和sem
  • 做淘宝客优惠券网站还是APP赚钱搜狗识图