简单分析数据被序列化后的内容

问题:

序列化后的结果json result :
[123 34 109 111 110 115 116 101 114 78 97 109 101 34 58 34 231 142 137 229 133 148 231 178 190 34 44 34 109 111 110 115 116 101 114 65 103 101 34 58 50 48 44 34 109 111 110 115 116 101 114 83 97 108 34 58 56 56 56 46 57 57 44 34 109 111 110 115 116 101 114 83 101 120 34 58 34 102 101 109 97 108 101 34 125]
以上切片中的数值都是8位二进制数转换后的吗?

是的,你看到的序列化结果中的数值确实是 8位二进制数(即字节,Byte)。这些数值是将 JSON 字符串按照 UTF-8 编码序列化为字节切片 ([]byte) 后的输出结果。

解释

当我们将 JSON 对象序列化时,例如使用 json.Marshal 函数,它会将 JSON 对象转换成 UTF-8 编码的字节数组。在 UTF-8 编码中,每个字符都会被编码为一个或多个字节(8位二进制数)。具体来说:

  • ASCII 字符(如英文字符、数字、标点符号)编码成 1 个字节(即 8 位)。
  • 非 ASCII 字符(如中文字符、特殊符号)编码成 多个字节(通常是 3 个或更多字节)。

举例说明

假设我们有以下 Go 代码:

package mainimport ("encoding/json""fmt"
)type Person struct {MonsterName string  `json:"monsterName"`MonsterAge  int     `json:"monsterAge"`MonsterSal  float64 `json:"monsterSal"`MonsterSex  string  `json:"monsterSex"`
}func main() {p := Person{MonsterName: "怪兽",MonsterAge:  20,MonsterSal:  888.99,MonsterSex:  "female",}// 序列化为 JSONjsonData, err := json.Marshal(p)if err != nil {fmt.Println("序列化失败:", err)return}// 输出序列化后的字节切片fmt.Println("json result:", jsonData)// 输出序列化后的 JSON 字符串fmt.Println("json string:", string(jsonData))
}

输出结果

json result: [123 34 109 111 110 115 116 101 114 78 97 109 101 34 58 34 229 153 130 231 149 140 34 44 34 109 111 110 115 116 101 114 65 103 101 34 58 50 48 44 34 109 111 110 115 116 101 114 83 97 108 34 58 56 56 56 46 57 57 44 34 109 111 110 115 116 101 114 83 101 120 34 58 34 102 101 109 97 108 101 34 125]
json string: {"monsterName":"怪兽","monsterAge":20,"monsterSal":888.99,"monsterSex":"female"}

逐个解析字节

  • { 的 ASCII 码是 123。
  • " 的 ASCII 码是 34。
  • 怪 的 UTF-8 编码是 [229, 153, 130]。
  • 兽 的 UTF-8 编码是 [231, 149, 140]。
  • , 的 ASCII 码是 44。
  • 20 是两个 ASCII 数字字符 50(‘2’) 和 48(‘0’)。
  • female 是由 ASCII 字符组成的,分别是 102(‘f’), 101(‘e’), 109(‘m’), 97(‘a’), 108(‘l’), 101(‘e’)。

结论

  • JSON 序列化后的输出是一个 字节切片 ([]byte)。
  • 数组中的每个元素都是 8位二进制数(即字节),表示 UTF-8 编码的字符。
  • 你可以通过 string(jsonData) 将字节数组重新转换为可读的 JSON 字符串。

亲自动手尝试:

大家可以用下面的代码自己尝试一下:

要逐个解析 JSON 字符串对应的字节数组,我们可以通过 Go 的 []byte 类型来表示这些字节,并将其逐个打印出来。同时,将 JSON 字符串转换为字节数组后,可以看到 UTF-8 编码如何表示字符和数字。

示例 JSON 解析和逐字节分析

  • JSON 字符串:

    {"monsterName":"怪兽","monsterAge":20,"monsterSal":888.99,"monsterSex":"female"}
    
  • 对应的字节数组:

    [123 34 109 111 110 115 116 101 114 78 97 109 101 34 58 34 229 153 130 231 149 140 34 44 34 109 111 110 115 116 101 114 65 103 101 34 58 50 48 44 34 109 111 110 115 116 101 114 83 97 108 34 58 56 56 56 46 57 57 44 34 109 111 110 115 116 101 114 83 101 120 34 58 34 102 101 109 97 108 101 34 125]
    

我们可以通过 Go 程序来逐个解析这些字节,打印出每个字节及其对应的字符。

Go 代码实现逐字节解析

package mainimport ("fmt"
)func main() {// JSON 字符串jsonString := `{"monsterName":"怪兽","monsterAge":20,"monsterSal":888.99,"monsterSex":"female"}`// 将 JSON 字符串转换为字节数组jsonBytes := []byte(jsonString)fmt.Println("逐个解析字节:")fmt.Printf("%-10s %-10s %-15s\n", "Index", "Byte", "Character")fmt.Println("----------------------------------------")// 遍历字节数组for i, b := range jsonBytes {// 打印字节的索引、字节值、以及对应的字符fmt.Printf("%-10d %-10d %-15q\n", i, b, b)}
}

解析结果示例

逐个解析字节:
Index      Byte       Character         
----------------------------------------
0          123        '{'               
1          34         '"'               
2          109        'm'               
3          111        'o'               
4          110        'n'               
5          115        's'               
6          116        't'               
7          101        'e'               
8          114        'r'               
9          78         'N'               
10         97         'a'               
11         109        'm'               
12         101        'e'               
13         34         '"'               
14         58         ':'               
15         34         '"'               
16         230        'æ'               
17         128        '\u0080'          
18         170        'ª'               
19         229        'å'               
20         133        '\u0085'          
21         189        '½'               
22         34         '"'
23         44         ','
24         34         '"'
25         109        'm'
26         111        'o'
27         110        'n'
28         115        's'
29         116        't'
30         101        'e'
31         114        'r'
32         65         'A'
33         103        'g'
34         101        'e'
35         34         '"'
36         58         ':'
37         50         '2'
38         48         '0'
39         44         ','
40         34         '"'
41         109        'm'
42         111        'o'
43         110        'n'
44         115        's'
45         116        't'
46         101        'e'
47         114        'r'
48         83         'S'
49         97         'a'
50         108        'l'
51         34         '"'
52         58         ':'
53         56         '8'
54         56         '8'
55         56         '8'
56         46         '.'
57         57         '9'
58         57         '9'
59         44         ','
60         34         '"'
61         109        'm'
62         111        'o'
63         110        'n'
64         115        's'
65         116        't'
66         101        'e'
67         114        'r'
68         83         'S'
69         101        'e'
70         120        'x'
71         34         '"'
72         58         ':'
73         34         '"'
74         102        'f'
75         101        'e'
76         109        'm'
77         97         'a'
78         108        'l'
79         101        'e'
80         34         '"'
81         125        '}'

解释

  • UTF-8 编码

    • 中文字符 "怪" 的 UTF-8 编码是 [229, 153, 130]
    • 中文字符 "兽" 的 UTF-8 编码是 [231, 149, 140]
  • ASCII 字符

    • 例如,字符 { 的 ASCII 值是 123
    • 字符 " 的 ASCII 值是 34
    • 数字 20 是以字符形式存储的,因此 20 的 ASCII 值分别是 5048

总结

  • JSON 字符串是以 UTF-8 编码 的字节数组表示的。
  • Go 的 []byte 类型可以帮助我们逐个访问 JSON 字符串中的每个字节。
  • 通过解析字节数组,我们可以看到 JSON 的每个字符(包括汉字)如何被编码和存储。

代码解惑

fmt.Printf("%-10d %-10d %-15q\n", i, b, b)

这行代码使用 fmt.Printf 函数来格式化并输出逐字节解析的结果:

代码详解

  • fmt.Printf 是 Go 语言中用于格式化输出的函数。它根据提供的格式化字符串输出变量的值。

  • %-10d %-10d %-15q 是格式化字符串,定义了输出的格式。我们来详细分解它:

    1. %-10d

      • %d 表示将一个整数(int 类型)以十进制形式输出。
      • -10 是一个格式化修饰符,表示左对齐,并保留 10 个字符的宽度。若实际内容不足 10 个字符,则在右侧补空格。
      • 作用:输出变量 i(索引值),并确保输出宽度至少为 10 个字符,左对齐。
    2. %-10d(再次出现):

      • 同样的解释,输出 b(字节的整数值),宽度为 10 个字符,左对齐。
    3. %-15q

      • %q 用于输出一个字符的 单引号括起来的字面量(即带引号的字符),对于 ASCII 字符会显示单引号括起来的字符,对于不可打印字符(如控制字符)则会以转义形式显示。
      • -15 表示左对齐,并保留 15 个字符的宽度。若字符长度不足 15,则在右侧补空格。
      • 作用:输出 b 对应的字符(如果可以打印),并确保输出宽度至少为 15 个字符,左对齐。
  • \n:表示换行符,使每次输出后都换到下一行。

示例输出分析

假设我们有如下的字节数组(部分 JSON 字符串的例子):

jsonBytes := []byte(`{"monsterName":"怪兽"}`)

遍历并逐字节输出:

for i, b := range jsonBytes {fmt.Printf("%-10d %-10d %-15q\n", i, b, b)
}
输出结果:
Index      Byte       Character      
----------------------------------------
0          123        '{'            
1          34         '"'            
2          109        'm'            
3          111        'o'            
4          110        'n'            
5          115        's'            
6          116        't'            
7          101        'e'            
8          114        'r'            
9          78         'N'            
10         97         'a'            
11         109        'm'            
12         101        'e'            
13         34         '"'            
14         58         ':'            
15         34         '"'            
16         229        '怪'           
17         153        (Unicode byte)  
18         130        (Unicode byte)  
19         231        '兽'           
20         149        (Unicode byte)  
21         140        (Unicode byte)  
22         34         '"'            
23         125        '}'            

输出解释

  • Index(索引):0 到 23,表示字节在数组中的位置。
  • Byte(字节值):以十进制显示对应的 ASCII 或 Unicode 值。例如,123{ 的 ASCII 值。
  • Character(字符表示):
    • 如果 b 对应的是 ASCII 字符,则以字符形式显示,如 {, ", m
    • 如果 b 是 Unicode 字符的一部分(如汉字 “怪” 的 3 个字节之一),则只显示单个字节的十进制值或 Unicode 组合字节。

总结

  • 这行代码使用 fmt.Printf 格式化输出字节数组内容,按 索引字节值字符表示 三列对齐显示。
  • 通过 %-10d%-15q 的格式控制,可以确保输出整齐,便于阅读和分析。
  • %q 格式化符号特别适合显示字符串和字符的字面值,同时处理 Unicode 和转义字符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18497.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

latex中,两个相邻的表格,怎样留一定的空白

目录 问题描述 问题解决 问题描述 在使用latex写论文时,经常表格需要置顶写,则会出现两个表格连在一起的情况。下一个表名容易与上面的横线相连,如何通过明令,留出一定的空白。 问题解决 在第二个表格的 \centering命令之后…

leetcode01——合并两个有序数组

0.本题学到的知识 1.python的操作中,哪些是在原数据上进行操作的? 新开辟的行为:list1list1[m:n] 原数据:list1[a:b]list1[m:n] 新开辟:list1list1list2 原数据:list1.append(list2[i]); list1.extend(list…

深度学习的艺术:揭秘卷积神经网络(CNN)的神秘面纱

深度学习的艺术:揭秘卷积神经网络(CNN)的神秘面纱 一、CNN的构成要素二、CNN的工作流程三、CNN的应用领域四、CNN的优势与局限 #引言: 在人工智能的璀璨星空中,卷积神经网络(CNN)如同一颗耀眼的…

Linux高阶——1116—环形队列生产者消费者

目录 1、环形队列 2、生产者消费者 环形队列数组实现代码 成功截图 1、环形队列 相比于线性队列,环形队列可以有效避免访问越界问题,使用下标访问队列元素时,到达末尾后下标归0,返回起始位置,使用下标运算即可 a…

学习大数据DAY61 宽表加工

目录 模型设计 加工宽表 任务调度: 大表 - 把很多数据整合起来 方便后续的明细查询和指标计算 模型设计 设计 建模 设计: excel 文档去编写 建模: 使用建模工具 PowerDesigner Navicat 在线画图工具... 把表结构给绘 制出来 共享\项目课工具\pd 加工宽表 数…

DBeaver MACOS 安装 并连接到docker安装的mysql

官网下载:Download | DBeaver Community 网盘下载:链接: https://pan.baidu.com/s/15fAhbflHO-AGc-uAnc3Rjw?pwdbrz9 提取码: brz9 下载驱动 连接测试 报错 null, message from server: "Host 172.17.0.1 is not allowed to connect to this M…

24首届数证杯(流量分析部分)

目录 流量分析 流量分析 1、分析网络流量包检材,写出抓取该流量包时所花费的秒数?(填写数字,答案格式:10) 3504相加即可 2、分析网络流量包检材,抓取该流量包时使用计算机操作系统的build版本是多少? 23F793、分析网络流量包检材&#x…

云服务器ECS经济型e实例和通用算力u1实例有啥区别?

阿里云服务器ECS经济型e实例怎么样?对比ECS通用算力型u1实例哪个更好?u1实例更好。阿里云服务器网aliyunfuwuqi.com二者均为云服务器ECS的实例规格,e实例是共享型云服务器,u1实例是独享型云服务器,何为共享&#xff1f…

QT中使用图表之QChart绘制柱状图

绘制条形(柱状)图,系列选择条形系列QBarSeries x轴选择条形图的种类轴QBarCategoryAxis 1、创建图表视图 //1、创建图表视图 QChartView * view new QChartView(this); //开启抗锯齿 view -> setRenderHint(QPainter::Antialiasing); …

Essential Cell Biology--Fifth Edition--Chapter one (8)

1.1.4.6 The Cytoskeleton [细胞骨架] Is Responsible for Directed Cell Movements 细胞质基液不仅仅是一种无结构的化学物质和细胞器的混合物[soup]。在电子显微镜下,我们可以看到真核细胞的细胞质基液是由长而细的丝交叉而成的。通常[Frequently],可…

【Linux】守护进程

目录 进程组 会话 作业控制 实现守护进程 我们在写完一些网络服务后,如果想让这个服务一直在云服务器的后台运行着,那该如何实现呢?其实就用到了这篇博客要讲的守护进程 进程组 我们首先需要了解进程组的概念,其实sleep 1000这…

nginx.conf配置文件中的命令

打开我们的conf文件 nginx.conf文件中,分为3大块: 全局块,就是events和http块之外的内容。设置nginx服务器整体运行的指令 格式为: 指令名 指令值 events块,用于配置与用户的网络连接的内容,对nginx的…

51单片机基础07 实时时钟-思路及代码参考1

目录 一、实现功能 二、思路1的分析 1、定时器0 2、外部中断0 3、主函数main 4、其他重要功能函数 一、实现功能 1、实现最基本的计时功能,显示时、分、秒,可以通过按键设置时间。 要求:时钟计时精确,按键操作不影响计时。…

vTESTstudio系列15--vTESTstudio-Doors的需求和测试用例的管理

最近有朋友在咨询vTESTstudio中怎么去跟Doors里面的需求去做好管理这方面的问题,临时加两篇文章介绍一下,Lets Go!!! 目录 1.Doors的配置: 1.1 安装Doors AddIn for vTESTstudio: 1.2 更新XML脚本: 1.3 导出需求的Trace Item…

基于Java Springboot编程语言在线学习平台

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…

JDK安装报错“以下应用程序正在使用需要由此安装程序更新的文件”

(一)问题描述 我刚刚没有截图,这是我在网上看到的图: (二)可能的解决办法 1. 下方工具栏右键,打开任务管理器按钮,在进程中找到“Java Platform SE binary” 进程,右键结…

数据库第3次作业

学生表:Student (Sno, Sname, Ssex , Sage, Sdept) 学号,姓名,性别,年龄,所在系 Sno为主键 课程表:Course (Cno, Cname,) 课程号,课程名 Cno为主键 学生选课表:SC (Sno, Cno, Score)…

Linux之文件系统,软硬连接和动静态库

Linux之文件系统,软硬连接和动静态库 一.文件系统1.1磁盘的存储结构1.2CHS和LBA1.3ext2文件系统 二.软硬连接2.1软链接2.2硬链接 三.静态库和动态库3.1静态库与动态库的概念3.2静态库的创建与使用3.3动态库的创建与使用3.4动态库的加载 一.文件系统 在上篇的学习中…

【项目开发】URL中井号(#)的技术细节

未经许可,不得转载。 文章目录 前言一、# 的基本含义二、# 不参与 HTTP 请求三、# 后的字符处理机制四、# 的变化不会触发网页重新加载五、# 的变化会记录在浏览器历史中六、通过 window.location.hash 操作七、onhashchange 事件八、Google 对 # 的处理机制前言 2023 年 9 月…

TikZ 绘图学习笔记

这篇笔记的所有代码如下: % !TEX TS-program pdflatex % !TEX encoding UTF-8 Unicode% This is a simple template for a LaTeX document using the "article" class. % See "book", "report", "letter" for other typ…