版权声明:本文为博主原创文章,欢迎转载。 https://blog.csdn.net/u010828718/article/details/80697425
由一个汉字二次编码,引起的知识补充
汉字二次编码:
文 -> (一次UFT-8编码)%E6%96%87 -> (二次UFT-8编码)%25E6%2596%2587
1 GB2312、GBK、GB18030与UTF-8的区别
- GB2312
- 国家标准,支持中文字符
GBK
- GB2312的拓展
- 不论中、英文字符均使用双字节来表示,中文将其最高位设定成1。
- 通用性比UTF8差,不过UTF8占用的数据库比GBD大
GB18030
- GBK的拓展
- 采用了2\4位混和的办法,兼容GB2312和GBK2字节编码的文件
UTF-8
- 全称:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM
- 英文使用8位(即一个字节),中文使用24位(三个字节)
- 包含全世界所有国家需要用到的字符,是国际编码,通用性强
2 相互转换
- 通过Unicode编码相互转换
3 ASCll编码和Unicode编码的区别
- ASCII编码
- 1个字节
- ASCII 码一共定义了 128 个字符
- 大写的字母 A 是 65(这是十进制数,对应二进制是0100 0001)
- 这 128 个字符只使用了 8 位二进制数中的后面 7 位,最前面的一位统一规定为 0
- Unicode编码
- 通常是2个字节,可以更多
- UTF-8编码
- 把Unicode字符根据不同的数字大小编码成1-4个字节
- 编码规则如下
- 对于单个字节的字符,第一位设为 0,后面的 7 位对应这个字符的 Unicode 码点,因此与 ASCII 码完全相同
- 对于 N 个字节的字符(N > 1),
- 第一个字节的前 N 位都设为 1,第 N + 1 位设为0
- 剩余的 N - 1 个字节的前两位都设位 10
- 剩下的二进制位则使用这个字符的 Unicode 码点来填充
UNICODE 十六进制码点范围 | UTF-8 二进制 |
---|---|
0000 0000 - 0000 007F | 0xxxxxxx |
0000 0080 - 0000 07FF | 110xxxxx 10xxxxxx |
0000 0800 - 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000 - 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
- 编码例子
- “汉”的 Unicode 码点是 0x6c49(110 1100 0100 1001),通过上面的对照表可以发现,0x0000 6c49 位于第三行的范围,那么得出其格式为 1110xxxx 10xxxxxx 10xxxxxx
- 接着,从“汉”的二进制数最后一位开始,从后向前依次填充对应格式中的 x,多出的 x 用 0 补上
- 这样,就得到了“汉”的 UTF-8 编码为 11100110 10110001 10001001,转换成十六进制就是 0xE6 0xB7 0x89
- 解码规则如下
- 如果一个字节的第一位是 0 ,则说明这个字节对应一个字符;
- 如果一个字节的第一位1,那么连续有多少个 1,就表示该字符占用多少个字节
4 iOS中URL编码和解码
4.1 为什么需要URL编码
- URL中有些字符会引起歧义
- 例如:URL参数字符串中使用键值对(key=value)的方式来传参,键值对之间以&符号分隔,因此键值中的&符号必须进行编码
- URL的编码格式采用的是ASCII码,而不是Unicode
- URL中不能包含任何非ASCII字符,例如中文
4.1 URL编码、解码
- URL编码的原则
- 就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符
- 中文、空格字符编码
- stringByAddingPercentEscapesUsingEncoding(只对 `#%^{}[]|\”<> 加空格共14个字符编码,不包括”&?”等符号)
- stringByAddingPercentEncodingWithAllowedCharacters( ios9)
NSString * resourcePath = @"https://www.baidu.com/文件夹"
// 编码
(iOS9.0以下使用)
NSString *str3 =[resourcePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
(iOS9.0以及以上使用)
NSString *str3 =
[resourcePath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
NSString *str3 =
[resourcePath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<>"].invertedSet];
- 中文、空格字符解码
- stringByReplacingPercentEscapesUsingEncoding
- stringByRemovingPercentEncoding (ios9)
NSString * resourcePath = @"https://www.baidu.com/文件夹";
// 解码
(iOS9.0以下使用)
NSString *str2 = [resourcePath stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
(iOS9.0以及以上使用):
NSString *str2 = [resourcePath stringByRemovingPercentEncoding];
4.2 NSCharacterSet 中的字符
URLFragmentAllowedCharacterSet
- ”#%<>[]^`{|}
URLHostAllowedCharacterSet
- ”#%/<>?@\^`{|}
URLPasswordAllowedCharacterSet
- ”#%/:<>?@[]^`{|}
URLPathAllowedCharacterSet
- ”#%;<>?[]^`{|}
URLQueryAllowedCharacterSet
- ”#%<>[]^`{|}
URLUserAllowedCharacterSet
- ”#%/:<>?@[]^`
5 原码、反码、补码
- 原码:一个整数,按照绝对值大小转换成的二进制数
- 最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小
- 比如5的原码:00000000 00000000 00000000 00000101
- 反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码
- 正数的反码与其原码相同
- 负数的反码是对其原码逐位取反,但符号位除外
- 取反操作指:原为1,得0;原为0,得1。(1变0; 0变1)
- 补码:反码加1称为补码
- 正数的补码和原码相同
- 负数以其正值的补码形式表达
- 比如5的补码(也就是-5的表达方式):11111111 11111111 11111111 11111011
- 无符号位取值范围
- 0~255 (因为计算机是从0开始计算的而不是1)
- 0~2^8 - 1 (256 -1)
- 有符号位取值范围
- -128 ~ +127
- -2^7(-128) ~ 2^7-1 (128-1)
6 URL中的特殊字符
- URL中只允许包含英文字母(a-zA-Z)、数字(0-9)、4个特殊字符(- _ . ~)以及所有保留字符,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了
- 编码的格式为:百分号(%)加字符的ASCII码(16进制)码值
符号 | 特殊含义 | 十六进制值 |
---|---|---|
部分保留字符 | ||
< | %3C | |
> | %3E | |
“ | 普通文本中起到分隔Url的作用 | %22 |
# | 通常用于表示书签或者锚点 | %23 |
% | 指定特殊字符 | %25 |
{ | %7B | |
} | %7D | |
\ | %5C | |
^ | 加字号 | %5E |
~ | 波浪 | %7E |
[ | %5B | |
] | %5D | |
` | 反单引号 | %60 |
空格 | %20 | |
* | %2A | |
‘ | %27 | |
( | %28 | |
) | %29 | |
+ | 表示空格(在URL中不能使用空格) | %2B |
$ | 表示空格(在URL中不能使用空格) | %24 |
, | 表示空格(在URL中不能使用空格) | %2C |
保留字符 | ||
; | %3B | |
/ | 分隔目录和子目录 | %2F |
? | 分隔实际的 URL 和参数 | %3F |
: | %3A | |
@ | %40 | |
= | %3D | |
& | URL中指定的参数间的分隔符 | %26 |
7 URL的格式
- URI(Uniform Resource Identifier):统一资源标识符
- 标识/定义资源
- URL(Uniform Resource Location):统一资源定位符
- 描述如何访问到该资源
protocol :// hostname[:port] / path / [;parameters][?query]#fragment
foo://example.com:8042/over/there?name=ferret#nose
\_/ \______________/ \________/\_________/ \__/
| | | | |
scheme authority path query fragment
- protocol(协议)
- 指定使用的传输协议,最常用的是HTTP协议
- hostname(主机名)
- 存放资源的服务器的域名系统(DNS) 主机名或 IP 地址
- port(端口号)
- 各种传输协议都有默认的端口号,如http的默认端口为80
- path(路径)
- 由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
- parameters(参数)
- 指定特殊参数的可选项
- query(查询)
- 可选,用于给动态网页传递参数,可有多个参数,用“&”符号隔开,每个参数的名和值用“=”符号隔开
- fragment(信息片断)
- 字符串,用来标识 URI 所标识资源里的某个资源
8 处理字符串的方法 :NSCharacterSet\NSMutableCharacterSet
- 常用API学习
//NSCharacterSet
/** 001 根据一个给定的字符串获取一个NSCharacterSet对象 */
+ (NSCharacterSet *)characterSetWithCharactersInString:(NSString *)aString;
/** 002 相反字符串限制 【具体见接下的例子】 */
@property (readonly, copy) NSCharacterSet *invertedSet;
/** 003 常用快捷方法集合 (常用的,已满足大多数需求) */
+ controlCharacterSet
+ whitespaceCharacterSet //空格
+ whitespaceAndNewlineCharacterSet //空格和换行符
+ decimalDigitCharacterSet //0-9的数字
+ letterCharacterSet //所有字母
+ lowercaseLetterCharacterSet //小写字母
+ uppercaseLetterCharacterSet //大写字母
+ alphanumericCharacterSet //所有数字和字母(大小写不分)
+ punctuationCharacterSet //标点符号
+ newlineCharacterSet //换行
//NSMutableCharacterSet
/** 001 功能同 invertedSet 方法一样,注意这个没有返回值 */
- (void)invert;
- 应用1:textFielf只能输入数字
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *charSet = [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
NSString *filteredStr = [[string componentsSeparatedByCharactersInSet:charSet] componentsJoinedByString:@""];
if ([string isEqualToString:filteredStr]) {
return YES;
}
return NO;
}
9 解析URL的方法 : NSURLComponents
初始化方法如下:
- (instancetype)init;
- (nullable instancetype)initWithURL:(NSURL *)url resolvingAgainstBaseURL:(BOOL)resolve;
+ (nullable instancetype)componentsWithURL:(NSURL *)url resolvingAgainstBaseURL:(BOOL)resolve;
- (nullable instancetype)initWithString:(NSString *)URLString;
+ (nullable instancetype)componentsWithString:(NSString *)URLString;
//常用的属性如下:
@property (nullable, readonly, copy) NSURL *URL;
@property (nullable, readonly, copy) NSString *string NS_AVAILABLE(10_10, 8_0);
@property (nullable, copy) NSString *scheme; // Attempting to set the scheme with an invalid scheme string will cause an exception.
@property (nullable, copy) NSString *user;
@property (nullable, copy) NSString *password;
@property (nullable, copy) NSString *host;
@property (nullable, copy) NSNumber *port; // Attempting to set a negative port number will cause an exception.
@property (nullable, copy) NSString *path;
@property (nullable, copy) NSString *query;
@property (nullable, copy) NSString *fragment;
@property (nullable, copy) NSString *percentEncodedUser;
@property (nullable, copy) NSString *percentEncodedPassword;
@property (nullable, copy) NSString *percentEncodedHost;
@property (nullable, copy) NSString *percentEncodedPath;
@property (nullable, copy) NSString *percentEncodedQuery;
@property (nullable, copy) NSString *percentEncodedFragment;
@property (nullable, copy) NSArray<NSURLQueryItem *> *queryItems NS_AVAILABLE(10_10, 8_0);
- 应用1: iOS 解析url中的key和value
NSString* wxNASAURLPath = @"http://www.ruyizi.com/url?a=1&b=2&c=3";
NSURLComponents* wxNASAURLComponents = [NSURLComponents componentsWithString:wxNASAURLPath];
NSMutableDictionary* queryItemDict = [NSMutableDictionary dictionary];
NSArray* queryItems = wxNASAURLComponents.queryItems;
for (NSURLQueryItem* item in queryItems) {
[queryItemDict setObject:item.value forKey:item.name];
}
参考
1 彻底弄懂 Unicode 编码
2 NSURL/NSURLComponents
3 percent-encode 百分号编码
4 URI’s fragment
5 学会NSCharacterSet,再也不怕各种字符串处理
6 NSURLComponents的使用