ios中的转码问题

版权声明:本文为博主原创文章,欢迎转载。 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的使用

猜你喜欢

转载自blog.csdn.net/u010828718/article/details/80697425