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

问题:

序列化后的结果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.rhkb.cn/news/475582.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT Search VS Kimi探索版:AI搜索哪家强?!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

【网络系统管理】Centos7——配置主从mariadb服务器案例(下半部分)

【网络系统管理】Centos7——配置主从mariadb服务器案例-CSDN博客 接上个文档,我们已经完成了主服务器创建数据库备服务器可以看到 一、在DBMS2查看信息 File,Position这两个字段的数据要记好,等一下需要用到 show master status; 二、在…

定长滑动窗口(LeetCode——1423.可获得的最大点数)

题目 . - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/maximum-points-you-can-obtain-from-cards 几张卡牌 排成一行…

ubuntu20.04如何升级python3.8到python3.10

主要参考了这两个链接: 如何在Ubuntu 20.04安装Python 3.10 | myfreaxhttps://www.myfreax.com/how-to-install-python-3-10-on-ubuntu-20-04/#:~:text%E5%9C%A8%E8%B0%83%E8%AF%95%E5%92%8C%E5%85%B6%E4%BB%96%E5%B7%A5%E5%85%B7%E4%B8%AD%E4%BD%BF%E7%94%A8%E7%B…

JDK安装和Linux常见设置详细版教程

一、Linux的常见设置 1、设置静态IP vi /etc/sysconfig/network-scripts/ifcfg-ens33 如何查看自己的虚拟机的网关: 完整的配置(不要拷贝我的): TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no&…

【Visual Studio系列教程】如何在 VS 上编程?

上一篇博客中,我们介绍了《什么是 Visual Studio?》。本文,我们来看第2篇《如何在 VS 上编程?》。阅读本文大约10 分钟。我们会向文件中添加代码,了解 Visual Studio 编写、导航和了解代码的简便方法。 本文假定&…

python: generator model using sql server 2019

設計或生成好數據庫,可以生成自己設計好的框架項目 # encoding: utf-8 # 版权所有 :2024 ©涂聚文有限公司 # 许可信息查看 :言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述: : 生成实体 # Author …

【Rabbitmq篇】RabbitMQ⾼级特性----消息确认

目录 前言: 一.消息确认机制 • ⾃动确认 • ⼿动确认 手动确认方法又分为三种: 二. 代码实现(spring环境) 配置相关信息: 1). AcknowledgeMode.NONE 2 )AcknowledgeMode.AUTO 3&…

【Pikachu】SSRF(Server-Side Request Forgery)服务器端请求伪造实战

尽人事以听天命 1.Server-Side Request Forgery服务器端请求伪造学习 SSRF(服务器端请求伪造)攻击的详细解析与防范 SSRF(Server-Side Request Forgery,服务器端请求伪造) 是一种安全漏洞,它允许攻击者通…

鸿蒙NEXT自定义组件:太极Loading

【引言】(完整代码在最后面) 本文将介绍如何在鸿蒙NEXT中创建一个自定义的“太极Loading”组件,为你的应用增添独特的视觉效果。 【环境准备】 电脑系统:windows 10 开发工具:DevEco Studio NEXT Beta1 Build Vers…

JSONObject jsonObject = JSON.parseObject(json);

是用于将一个 JSON 格式的字符串解析为一个 JSONObject 对象的语句。具体来说: JSON.parseObject(json): 作用: JSON 是 FastJSON 库提供的一个工具类。parseObject 方法可以将 JSON 格式的字符串(例如:{"key1&qu…

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析

目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …

【面试题】接口怎么测试?如何定位前后端的Bug?

接口怎么测试? 接口测试用来验证不同软件组件之间的交互是否正常。包括验证数据传输,参数传递,我在多个项目中有过测试接口的经验。(… 当进行接口测试时,会使用Postman和Python的Requests库。首先根据接口文档设计测…

.net6.0(.net Core)读取 appsettings.json 配置文件

① 新项目中创建名为 appsettings.json 的 json文件,内容为: {//数据库连接字符串:"ConnectionString": {"DBconn": "server127.0.0.1;databasedb;uidsa;pwd123456;Timeout600;EncryptTrue;TrustServerCertificateTrue;"…

应用于各种小家电的快充协议芯片

前言 随着快充技术的广泛应用,以往小家电的慢充模式已经满足不了人们对充电速度的要求,因此商家纷纷对小家电应用了诱骗取电快充协议芯片 例如(XSP16H),有了快充的支持小家电的充电速度有了很大的提升,节省了很多的充电…

ftrack 24.10全面升级:Autodesk Flame集成与多项新功能性能改进将发布

管理复杂项目绝非易事,但ftrack Studio的最新更新旨在简化这一过程。我们设计了这些增强功能,以优化大家的工作流、提高可用性,并让你们有更多时间专注于创意工作。 让我们来看看都有什么新内容吧! ​增强功能来优化工作流 轻松…

网络工程师教程第6版(2024年最新版)

网络工程师教程(第6版)由清华大学出版社出版,由工业和信息化部教育与考试中心组编,张永刚、王涛、高振江任主编,具体介绍如下。 相关信息: 出版社: 清华大学出版社 ISBN:9787302669197 内容简介: 本书是工业和信息化部教育与考试中心组织编写的考试用书。本书 根据…

Leetcode739.每日温度(HOT100)

链接 第一次暴力提交错误&#xff0c;超时了&#xff1a; class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {int n temperatures.size();vector<int> res(n,0);for(int i 0;i<n;i){int j i1;while(j<n){i…

java八股-SpringCloud-服务雪崩,服务降级,服务熔断

文章目录 服务雪崩服务降级服务熔断本章小结 服务雪崩 服务降级 服务熔断 本章小结 服务降级针对的是接口不可用&#xff0c;服务熔断针对的是整个服务不可用&#xff01;

cesium for unity的使用

先聊聊导入 看到这里的因该能够知道&#xff0c;官网以及网上绝大多数的方法都导入不进来&#xff0c;那么解决方法如下: 两个链接&#xff1a;按照顺序依次下载这两个tgz和zip&#xff0c;其中tgz为主要部分&#xff0c;zip为示例工程项目 如果您要查看示例工程项目的话&am…