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

问题:

序列化后的结果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 main

import (
    "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",
    }

    // 序列化为 JSON
    jsonData, 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 main

import (
	"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 和转义字符。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

世界坐标系、相机坐标系、图像物理坐标系、像素平面坐标系

坐标系及其转换在计算机视觉领域占据核心地位。理解如何从一个坐标系转换到另一个坐标系,不仅是理论上的需要,也是实际应用中不可或缺的技能。 一、世界坐标系的定义 世界坐标系是一个全局的坐标系统,用于定义场景中物体的位置。在这个坐标…

03-axios常用的请求方法、axios错误处理

欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…

Redis/Codis性能瓶颈揭秘:网卡软中断的影响与优化

目录 现象回顾 问题剖析 现场分析 解决方案 总结与反思 1.调整中断亲和性(IRQ Affinity): 2.RPS(Receive Packet Steering)和 RFS(Receive Flow Steering): 近期,…

openwebui使用

文章目录 1、feature2、安装使用2.1 安装过程2.2 安装好后 1、feature 可以加载多个大模型 同时回复 模型问答: 使用vLLM框架部署模型,再使用Open WebUI直接进行模型问答 多模型支持: 多模型回复比对(Qwen2-72B-Instruct, llama3-70b-8192, mixtral-8x7…

汽车资讯新引擎:Spring Boot技术领航

3系统分析 3.1可行性分析 通过对本汽车资讯网站实行的目的初步调查和分析,提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本汽车资讯网站采用SSM框架,JAVA作为开发语言&#…

应用系统开发(12) Zync中实现数字相敏检波

在 Xilinx Zynq 系列(如 Zynq-7000 或 Zynq UltraScale+)中实现数字相敏检波(DSP,Digital Synchronous Detection)可以通过硬件(PL部分,FPGA逻辑)和软件(PS部分,ARM Cortex-A 处理器)的协同工作来实现。以下是一个详细的设计方法,包括基本原理和 Zynq 的实现步骤。…

《译文》2024年11月数维杯国际大学生数学建模挑战赛题目

# 赛题正式发布 2024年第十届数维杯国际大学生数学建模挑战赛顺利开赛,竞赛开始时间为北京时间2024年11月15日09:00至北京时间2024年11月19日09:00,共计4天,竞赛题目正式发布,快来一起围观,你认为今年的哪个题目更具有…

apk反编译修改教程系列-----apk应用反编译中AndroidManifest.xml详细代码释义解析 包含各种权限 代码含义【二】

💝💝💝💝在上期博文中解析了一个常规apk中 AndroidManifest.xml的权限以及代码。应粉丝需求。这次解析一个权限较高的apk。这款apk是一个家长管控的应用。需求的各种权限较高。而且通过管控端可以设置控制端的app隐藏与否。 通过博文了解💝💝💝💝 1💝💝…

【UGUI】背包的交互01(道具信息跟随鼠标+道具信息面板显示)

详细程序逻辑过程 初始化物品栏: 在 Awake 方法中,通过标签找到提示框和信息面板。 循环生成10个背包格子,并为每个格子设置图标和名称。 为每个格子添加 UInterMaager232 脚本,以便处理交互事件。 关闭提示框和信息面板&#…

Docker: ubuntu系统下Docker的安装

安装依赖 操作系统版本 Ubuntu Kinetic 22.10Ubuntu Jammy 24.04 (LTS)Ubuntu Jammy 22.04 (LTS)Ubuntu Focal 20.04 (LTS)Ubuntu Bionic 18.04 (LTS) CPU架构支持 ARMx86_64 查看我们的系统版本信息 uname -a通过该命令查得cpu架构是x86_64的; cat /etc/*re…

Nacos 配置中心变更利器:自定义标签灰度

作者:柳遵飞 配置中心被广泛使用 配置中心是 Nacos 的核心功能之一,接入配置中心,可以实现不重启线上应用的情况下动态改变程序的运行期行为,在整个软件生命周期中,可以极大降低了软件构建及部署的成本,提…

基于RK3568J多网口电力可信物联网关解决方案

前言 随着工业物联网的普及和功能越来越强大,边缘计算网关应运而生。 边缘计算有效降低了云端服务器的负载、大大降低了带宽的占用,同时也为本地化的区域自治提供了便利条件。 边缘计算网关,完美地发挥了“边”与“端” 结合优势&#xff0c…

无人机飞手入门指南

无人机飞手入门指南旨在为初学者提供一份全面的学习路径和实践建议,帮助新手快速掌握无人机飞行技能并了解相关法规知识。以下是一份详细的入门指南: 一、了解无人机基础知识 1. 无人机构造:了解无人机的组成部分,如机身、螺旋桨…

网络传输:网卡、IP、网关、子网掩码、MAC、ARP、路由器、NAT、交换机

目录 网卡IP网络地址主机地址子网子网掩码网关默认网关 MACARPARP抓包分析 路由器NATNAPT 交换机 网卡 网卡(Network Interface Card,简称NIC),也称网络适配器。 OSI模型: 1、网卡工作在OSI模型的最后两层,物理层和数据链路层。物…

多账号登录管理器(淘宝、京东、拼多多等)

目录 下载安装与运行 解决什么问题 功能说明 目前支持的平台 功能演示 登录后能保持多久 下载安装与运行 下载、安装与运行 语雀 解决什么问题 多个账号的快捷登录与切换 功能说明 支持多个电商平台支持多个账号的登录保持支持快捷切换支持导入导出支持批量删除支持…

你可以通过以下步骤找到并打开 **Visual Studio 开发者命令提示符**:

你可以通过以下步骤找到并打开 Visual Studio 开发者命令提示符: 1. 通过开始菜单查找 打开 开始菜单(点击屏幕左下角的 Windows 图标)。在搜索框中输入 Developer Command Prompt。你应该看到以下几种选项(具体取决于你的 Visu…

版本控制【Git Bash】【Gitee】

目录 一、什么是版本控制? 二、版本控制的种类: 1、本地版本控制 2、集中版本控制 3、分布式版本控制 三、下载Git Bash 四、Git Bash 配置 五、Git Bash使用 1、切换目录:cd 2.查看当前文件路径:pwd 3.列出当前目录下文件…

大数据-226 离线数仓 - Flume 优化配置 自定义拦截器 拦截原理 拦截器实现 Java

点一下关注吧!!!非常感谢!!持续更新!!! Java篇开始了! 目前开始更新 MyBatis,一起深入浅出! 目前已经更新到了: Hadoop&#xff0…

【3D Slicer】的小白入门使用指南九

定量医学影像临床研究与实践 任务 定量成像教程 定量成像是从医学影像中提取定量测量的过程。 本教程基于两个定量成像的例子构建: - 形态学:缓慢生长肿瘤中的小体积变化 - 功能:鳞状细胞癌中的代谢活动 第1部分:使用变化跟踪模块测量脑膜瘤的小体积变化第2部分:使用PET标…

Visual Studio 圈复杂度评估

VisualStudio自带的有工具 之后就可以看到分析结果