所謂大端數據就是數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;這和我們的閱讀習慣一致。
所謂的小端數據就是數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低。(簡單的來說就是反過來存放數據了)
數據補位,是指在將數據按照8個字節一段進行加密或解密得到一段8個字節的密文或者明文,最後一段不足8個字節,按照需求補足8個字節(通常補00或者FF,根據實際要求不同)進行計算,之後按照順序將計算所得的數據連在一起即可。
假設要發送一段這樣的數據(16進制數據):
| head | cmdlen(2字節) | cmd | playloadLen (4 字節) | playload
這段數據的內容大概是包含了:我有一個頭部標記,然後用頭部之後的兩個字節作為描述何種命令的長度,然後接上的是何種命令,然後接上了附帶信息的長度(4個字節),然後是附帶信息。
需要發送的信息為:| https(頭部) | len | openStream | len2 | {@"速度與激情.h264",@"fileName"}
// // CtpTools.m // NetworkTest // // Created by 飛天江郎 on 10/11/2016. // Copyright ? 2016 EzioChen. All rights reserved. // //普通字符串轉換為十六進制的。 + (NSString *)hexStringFromString:(NSString *)string { NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding]; Byte *bytes = (Byte *)[myD bytes]; //下面是Byte 轉換為16進制。 NSString *hexStr=@""; for(int i=0;i<[myD length];i++) { NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff];///16進制數 if([newHexStr length]==1) hexStr = [NSString stringWithFormat:@"%@0%@",hexStr,newHexStr]; else hexStr = [NSString stringWithFormat:@"%@%@",hexStr,newHexStr]; } return hexStr; } //編寫一個NSData類型數據 +(NSMutableData*)HexStringToData:(NSString*)str { NSString *command = str; command = [command stringByReplacingOccurrencesOfString:@" " withString:@""]; NSMutableData *commandToSend= [[NSMutableData alloc] init]; unsigned char whole_byte; char byte_chars[3] = {'\0','\0','\0'}; int i; for (i=0; i < [command length]/2; i++) { byte_chars[0] = [command characterAtIndex:i*2]; byte_chars[1] = [command characterAtIndex:i*2+1]; whole_byte = strtol(byte_chars, NULL, 16); [commandToSend appendBytes:&whole_byte length:1]; } return commandToSend; } //補位的方法 +(NSString*)addString:(NSString*)string Length:(NSInteger)length OnString:(NSString*)str { NSMutableString * nullStr = [[NSMutableString alloc] initWithString:@""]; if ((length-str.length)> 0) { for (int i = 0; i< (length-str.length); i++) { [nullStr appendString:string]; } } return [NSString stringWithFormat:@"%@%@",nullStr,str]; } //把整型轉化為16進制的,然後在補位,轉換成大端數據 +(NSString *)intToHexString:(NSInteger)number length:(NSInteger)len { NSString *result = [self addString:@"0" Length:len OnString:[self ToHex:(unsigned int)number]]; NSData *data = [self HexStringToData:result]; NSData *lastData = [self dataTransfromBigOrSmall:data]; result = [self dataChangeToString:lastData]; return result; } //把int 變成 16進制的字符串 +(NSString *)ToHex:(unsigned int)number { NSString * result = [NSString stringWithFormat:@"%x",number]; if (result.length<2) { result = [NSString stringWithFormat:@"0%x",number]; } return [result uppercaseString]; } //把data(十六進制)轉化為為十進制整型 +(NSInteger)dataToInt:(NSData *)data { NSInteger temp; double sum = 0.0; NSString * string = [self dataChangeToString:data]; NSInteger length = string.length; for (int i = 0 ; i < length; i++) { NSString * tempStr = [string substringWithRange:NSMakeRange(i, 1)]; int tempInt = [self StringToInt:tempStr]; double tempDouble = tempInt * pow(16.0, (double)(length-1-i)); sum = sum + tempDouble; } temp = (NSInteger)sum; return temp; } //大小端數據轉換(其實還有更簡便的方法,不過看起來這個方法是最直觀的) +(NSData *)dataTransfromBigOrSmall:(NSData *)data{ NSString *tmpStr = [self dataChangeToString:data]; NSMutableArray *tmpArra = [NSMutableArray array]; for (int i = 0 ;i" withString:@""]; string = [string stringByReplacingOccurrencesOfString:@" " withString:@""]; return string; } +(int)StringToInt:(NSString*)string{ int temp; temp = [string intValue]; if ([string isEqual:@"a"]||[string isEqual:@"A"]) { temp = 10; }else if ([string isEqual:@"b"]||[string isEqual:@"B"]) { temp = 11; }else if ([string isEqual:@"c"]||[string isEqual:@"C"]) { temp = 12; }else if ([string isEqual:@"d"]||[string isEqual:@"D"]) { temp = 13; }else if ([string isEqual:@"e"]||[string isEqual:@"E"]) { temp = 14; }else if ([string isEqual:@"f"]||[string isEqual:@"F"]) { temp = 15; } return temp; } //hexString 轉換成 String + (NSString *)stringFromHexString:(NSString *)hexString { char *myBuffer = (char *)malloc((int)[hexString length] / 2 + 1); bzero(myBuffer, [hexString length] / 2 + 1); for (int i = 0; i < [hexString length] - 1; i += 2) { unsigned int anInt; NSString * hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)]; NSScanner * scanner = [[NSScanner alloc] initWithString:hexCharStr]; [scanner scanHexInt:&anInt]; myBuffer[i / 2] = (char)anInt; } NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4]; return unicodeString; }
NSString *headStr = @"https"; NSString *playload = @"{\"fileName\":\"速度與激情.h264\"}"; NSString *cmd = @"openStream"; NSString *headHex = [self hexStringFromString:headStr]; NSString *cmdHex = [self hexStringFromString:cmd]; NSString *cmdLen = [self intToHexString:cmdHex.length/2 length:4]; NSString *playloadHex = [self hexStringFromString:playload]; NSString *playloadHexLen = [self intToHexString:playloadHex.length/2 length:8];NSString *allHexStr = [self stringWithFormat:@"%@%@%@%@%@",headHex,cmdLen,cmdHex,playloadHexLen,playloadHex]; NSData *lastData = [self HexStringToData:allHexStr]; NSLog(@"lastData=>%@",lastData);
最後打印出的Data,就是對應數據的16進制標准格式了。
其實還有一些可優化的地方,仔細的觀察下每次的Data組裝,然後你就會發現NSData本來就已經是16進制的,而大小端的轉換其實還有跟簡單的轉換比方說是這種:
#include#define ntohs(x) __DARWIN_OSSwapInt16(x) #define htons(x) __DARWIN_OSSwapInt16(x) #define ntohl(x) __DARWIN_OSSwapInt32(x) #define htonl(x) __DARWIN_OSSwapInt32(x)
這裡寫成這樣完全是方便理解。