1:MUTF-8字符串
MUTF-8意为Modified UTF-8,修改过的UTF-8编码
MUTF-8的特点: 1:使用1-3字节编码长度 2:对于大于16位Unicode编码使用3字节编码 3:对于U+0x0000,采用2字节编码 4:采用类似C语言的 ‘\0’ 作为字符串结束标志(小重点)
高级小重点:MUTF-8字符串头部存放uleb128编码表示的字符个数
2:uleb128编码:
由1-5字节组成,所有字节组合在一起表示一个32位的数,每一个字节的最高位表示uleb128是否在本字节停止,按位组合有效位拿到的结果也就是在uleb128之后的真正的字符串的长度。
其中,每当一个低字节的最高位为零,那么,就表示这个uleb128数仍未结束,最高判定到第四字节,如果仍旧大于0x7f,那么就直接和第五字节一起运算。
高级小重点:根据uleb128拿到所表示int值
int result = *(start++);
if (result > 0x7f) {
count++;
int cur = *(start++);
result = (result & 0x7f) | ((cur & 0x7f) << 7);
if (cur > 0x7f) {
count++;
cur = *(start++);
result |= ((cur & 0x7f) << 14);
if (cur > 0x7f) {
count++;
cur = *(start++);
result |= ((cur & 0x7f) << 21);
if (cur > 0x7f) {
cur = *(start++);
count++;
result |= (cur << 28);
}
}
}
}
start为指向uleb128起始位置的指针
count的意义在于记录这个uleb128数到底占了多少字节,以便加上字符串的字节数,提取下一个uleb128表示的字符串
3:提取出真实的字符串
注:由于编码的问题,我们不能通过前方计算出的uleb128真实int值就作为后边字符串的字节数,例如:02 e4 bd a0 e5 a5 bd 00,第一个字节小于0x7f,也就是uleb128数为2,两个字符,表示汉字的“你好”,可是他们有6个字节,所以我们通过判断 ‘\0’ 的方式决定字符串长度
那有人就要问了,那这个uleb128有啥用呢? 可能 是节省空间 吧,俺也想问,可能是俺太菜了
好了,接下来就可以提取字符串了,接上边计算uleb128真实值的程序
小贴士:start指针已经到了真实字符串的初始位置,只需拿到长度,然后copy一下子,完事
char* tmp = start;
while ((*start) != '\0') {
start++;
lengthOfString++;
}
str = malloc(lengthOfString + 1);
memset(str, 0, lengthOfString + 1);
memcpy(str, tmp, lengthOfString);
好啦,这样就基本完工啦,最后构造一个结构体对象出来,保存一下这个MUTF-8字符串的所有细节,就可以返回啦,如下
struct uleb128 a = { count,result,lengthOfString ,str };
return a;
count就是上方计算出的uleb前缀真实字节长度,result为uleb表示的字符个数,接着是字符串长度,字符串真实内容
4:MUTF-8字符串提取终章
这是我对这个字符串详细信息的定义,结合上方返回值一起食用
struct uleb128 {
int lengthOfHead;
int resultOfleb;
int lengthOfString;
char* content;
};
附注:跳过uleb128直接提取有效字符串
你可能发现了,uleb128这部分好像并没有太大用处,我本身是为了提取出所有内容的,那,额,好的,那就,拿到uleb128起始地址直接提取真实字符串的方法,代码如下,原理同上,跳过uleb128部分
while (*(start++) > 0x7f);
char* tmp = start;
while ((*start) != '\0') {
start++;
lengthOfString++;
}
str = malloc(lengthOfString + 1);
memset(str, 0, lengthOfString + 1);
memcpy(str, tmp, lengthOfString);
struct uleb128 a = { count,result,lengthOfString ,str };
return a;
5:完整代码
struct MUTF-8 {
int lengthOfHead;
int resultOfleb;
int lengthOfString;
char* content;
};
struct MUTF-8 Uleb128(char* start) {
int count = 1;
int lengthOfString = 0;
char* str = NULL;
int result = *(start++);
if (result > 0x7f) {
count++;
int cur = *(start++);
result = (result & 0x7f) | ((cur & 0x7f) << 7);
if (cur > 0x7f) {
count++;
cur = *(start++);
result |= ((cur & 0x7f) << 14);
if (cur > 0x7f) {
count++;
cur = *(start++);
result |= ((cur & 0x7f) << 21);
if (cur > 0x7f) {
cur = *(start++);
count++;
result |= (cur << 28);
}
}
}
}
char* tmp = start;
while ((*start) != '\0') {
start++;
lengthOfString++;
}
str = malloc(lengthOfString + 1);
memset(str, 0, lengthOfString + 1);
memcpy(str, tmp, lengthOfString);
struct MUTF-8 a = { count,result,lengthOfString ,str };
return a;
}
char* Uleb128Skip(char* start) {
int lengthOfString = 0;
char* str = NULL;
while (*(start++) > 0x7f);
char* tmp = start;
while ((*start) != '\0') {
start++;
lengthOfString++;
}
str = malloc(lengthOfString + 1);
memset(str, 0, lengthOfString + 1);
memcpy(str, tmp, lengthOfString);
return str;
}
结束啦,感谢浏览,如有错误,欢迎指导
|