首页 > 其他分享 >逆向——字符与字符串,中文字符GB2312编码由来

逆向——字符与字符串,中文字符GB2312编码由来

时间:2023-08-02 18:31:35浏览次数:42  
标签:字符 存储 逆向 打印 GB2312 编码 printf

字符与字符串

在之前的课程中我们了解到变量的定义决定两个事情,第一是决定存储的数据宽度,第二是决定了存储的数据格式,那么我们来看下下面的代码:

int a = 123; // 变量x,数据宽度为4个字节,里面存储的是补码(在计算机系统中,数值一律用补码来存储)


intfloat b = 123.4F; // IEEE编码(浮点)


int c = 'A'; // 那这个存储的是啥?

 

我们在代码中写了变量c,但是它最终存储进去的是啥呢?我们看下反汇编:

逆向——字符与字符串,中文字符GB2312编码由来_数据

在这里'A'存储的时候变成了0x41,这是为什么?因为它是一个字符,这里需要注意在变量定义赋值时,赋值字符需要加上单引号。

在内存中所有东西最终都会变成0和1,A对应0x41,那么可以大胆猜测一下B就是对应0x42,当我们使用字符存储到内存时,字符自然是没办法存储到内存中的,这时候就有了一个字符对应的表:ASCII表(美国标准信息交换代码)

这张表有128个符号,都是比较常用的,那也就是说在我们赋值A给变量时,编译器会去这张表中寻找大写的A,如上图所示A对应10进制为65,转为16进制就是0x41。

值得注意的是在这张表中最多也就是占用一个字节的宽度,所以我们完全没有必要使用int来存储字符,可以选择char,例如:char a = 'A';

在很多书中会描述char就是用来存储字符的,这是一个错误的说法,数据的存储是由使用者决定的而不是计算机。

C语言会自带很多函数提供我们使用,我们想要在控制台中输出一个字符,可以使用putchar这个函数:

putchar(65);


putchar('A');

如上代码就是输出一个字符A,这样我们就了解了这个函数的运行本质:将对应数从ASCII表中查出画在(打印)控制台上;需要注意该函数一次只能打印一个字符。

除了这个函数外还有一个打印输出的函数:printf,它就可以一次性打印多个字符。

#include <stdio.h>
 

void main()

{

 printf("Hello World!\n");

 

int x = 0xFFFFFFFF;


 printf("%d %u %x\n",x,x,x);


// -1 4294967295 ffffffff

 

float f = 3.1415F;


 printf("%6.2f\n",f);


// 3.14

}

使用printf函数需要在代码开头写#include <stdio.h>,三个printf分别表示输出字符串、整数、浮点数。

有心之人可能会发现在使用printf函数时,有好几个百分号的东西,这就叫做占位符,一共分为如下这几种:

%d 有符号数形式打印

%u 无符号形式打印

%x 16进制形式打印

%{x.y}f 打印浮点数 x标志打印总长度 y 代表小数点后长度

看过示例代码之后,我们就知道了字符串本质上就是一堆字符连续串在一块,观察一下反汇编代码:

逆向——字符与字符串,中文字符GB2312编码由来_逆向分析_02

这时候就存在一个问题,printf为什么会知道打印完最后一个感叹号之后就不打印了呢?这是因为在这一串字符串后存在着一个00,当printf看见之后就会停止打印了,也就是说字符串的结束标志在内存中是00。

我们想使用char类型来存储字符串,就需要用到数组,例如:

char buffer[20] = "Hello World!";


printf("%s\n",buffer);

这就表示buffer可以存储20个字符,%s是占位符,表示以字符串形式打印,关于数组的细节后面的课程中会学习到,这里了解一下即可。

中文字符

在之前了解到ASCII码表中,我们并没有发现存在中文,那么如何在计算机中存储中文?这时候我们需要了解一个新的表:拓展ASCII码表 (EASCII)

该表十进制值从128到255,但是这些也没办法满足我们中文的需求,所以天朝专家把那些127号后的奇异符号们 (即EASCII)取消掉,规定:一个小于127的字符意义与原来相同,但是两个大于127的字符连在一起时,就表示一个汉字,这样我们就可以组合出大约7000多个简体汉字了。

在这些编码里,连在ASCII里本来就有的数字、标点、字母都统统编了两个字节长的编码,这就是常说的”全角“字符,而原来在127号以下的那些就叫”半角“字符了,上述编码规则就是GB2312或GB2312-80。

GB2312或GB2312-80,两种编码可能使用相同的数字代表两个不同的符号,或者使用相同的数字代表不同的符号,这种编码方式有很大的弊端,当此种编码方式的数据在其他国家使用的时候,如果其他国家使用类似的编码规则,那么数据就会失去原本的意义

而前辈们早就发现了这种情况,因此Unicode编码就是为了解决这个问题才出现的。

在C语言中写入中文与其他字符串没区别,但我们了解过GB2312或GB2312-80编码规则后,就要知道一个中文代表2个字节:

char buffer[20] = "中国";


printf("%s\n",buffer);

逆向——字符与字符串,中文字符GB2312编码由来_赋值_03

标签:字符,存储,逆向,打印,GB2312,编码,printf
From: https://blog.51cto.com/u_11908275/6941645

相关文章

  • golang json字符串转结构体
    1、不知道结构体类型的情况下funcJsonStringToMap(jsonStrstring)(map[string]interface{},error){//未知值类型m:=make(map[string]interface{})err:=json.Unmarshal([]byte(jsonStr),&m)iferr!=nil{fmt.Printf("Unmarshalwither......
  • v_jstools js逆向分析工具
    1.工具地址:https://github.com/cilame/v_jstools2.下载文件文件下载下来以后,复制到桌面,然后解压到当前文件夹,会看到一个  v_jstools-main 的文件夹。3.插件安装谷歌浏览器地址栏输入如下url,打开扩展程序页面,并打开开发者模式:chrome://extensions/打开后,点击......
  • Python 字符串
    类数组>>>hello="Hello,World">>>print(hello[1])e>>>print(hello[-1])d获取位置 1 或最后的字符循环>>>forcharin"foo":...print(char)foo遍历单词 foo 中的字母切片字符串┌───┬───┬───┬───┬───┬───┬───┐|m|y|b|......
  • 代码随想录算法训练营第四十三天| 583. 两个字符串的删除操作 72. 编辑距离
    583.两个字符串的删除操作要求:删除最少的步数,来让这两个字符串相等思路:求末尾的最长公共子序列的长度,然后减去他们的长度代码:1//要求:两个字符串,删除任意一个字符后,让这两个字符相等2//dp[n][m]以n-1结尾的字符串变成节点为m-1为子序列的最大个数3//4//求......
  • 字符串解密
    题目描述小明在玩一个数字加减游戏,只使用加法或者减法,将一个数字变成数字每个回台,小明可以用当前的数字加上或减去一个数字现在有两种数字可以用来加减,分别为其中数字没有使用次数限制请问小明最少可以用多少次,才能将数字变成数字题目保证数字一定能变成数字输入描述输入的唯一一行......
  • 通过pattern来匹配字符串,Pattern类的compile方法,接收一个字符串作为匹配模板
    publicstaticStringextractSubstring(Stringinput,Stringpattern){PatternregexPattern=Pattern.compile(pattern);Matchermatcher=regexPattern.matcher(input);if(matcher.find()){returnmatcher.group(1);}returnnull;}input......
  • C语言, 字符串
    #include<stdio.h>#include<stdlib.h>#include<string.h>char*tt3="web数学算法";intstr_comparer(){//字符串是个指向字符串开头的指针char*tt1="aac";char*tt2="aa";//字符串可以直接转换成整数,前面加......
  • ISODate转换成字符串格式日期
     >db.tb_time_test.find(){"_id":ObjectId("64c9cc1ffb4c9e5dcd00cfa2"),"id":1,"time":ISODate("2023-08-02T11:23:11Z")}{"_id":ObjectId("64c9cc83fb0a738bc82bdbaf"),"......
  • app逆向之如何随机生成imei号
    importrandomdefgenerate_imei():#跟useragent类似,要变换一下##生成随机的TAC(前六位)tac=''.join(random.choices('0123456789',k=6))#生成随机的FAC(接下来的两位)fac=''.join(random.choices('0123456789',k=2))......
  • APP逆向之AES加密算法
    importrandomfromCrypto.CipherimportAESimportbase64#加密的字符串,必须是固定长度,处理成固定长度defpad_data(data):#计算需要填充的字节数pad_len=AES.block_size-(len(data)%AES.block_size)#使用填充字节进行填充padding=bytes([......