Objective
转载自:http://blog.csdn.net/remember_17/article/details/77337534?locationNum=10&fps=1
In the development of Bluetooth project, will encounter some problems related to data processing, this article on these issues have been basic collation and share to everyone. Contains the following three areas of content.
- Introduction to Data Size end
- Conversion of the size-end data mode
- Bitwise operation, left SHIFT, right shift operation
First, the data size end of the introduction
Online about data size end of the introduction of a large pile, in order to make the article comprehensive point, this article also briefly explain this aspect.
A. The size end indicates the order in which the data is stored on the computer.
B. Big-endian pattern conforms to human normal thinking, high-byte memory is kept in low address.
C. Small terminal mode convenient computer processing, high-byte storage in memory high address.
D. The default is small-end storage in iOS.
You can run the following two lines of code in Xcode and print out the size-end mode.
short int number = 0x8866;NSLog(@"%@",[NSString stringWithFormat:@"%x",((char *)&number)[0]].intValue == 66 ? @"小端模式" : @"大端模式");
Second, the size of the end of the data mode conversion
Bluetooth communication, the data received from the hardware is the NSData type, we need to parse the data in order to get the real user-friendly data.
But the received data in memory in the order of preservation may be the opposite of what we want, so in the process of parsing involves the conversion of the size side.
The size-to-end conversion of iOS is very handy, and in Apple's core fundation, it provides a way to do these data processing. Apple official documentation
Let me take a few examples and take a look at the basic use of the methods associated with the size side in Fundation.
1, Cfbyteordergetcurrent ()
Returns the size end mode of the current computer
CFByteOrderGetCurrent()返回的值是一个如下的枚举enum __CFByteOrder { CFByteOrderUnknown, // 未知的 CFByteOrderLittleEndian, // 小端模式 CFByteOrderBigEndian // 大端模式};
2, CFSwapInt16 ()
Convert a 16-bit integer number
// 把数字15转换模式CFSwapInt16(15)// 上面运算得到的结果十进制为3840,十六进制为0xF00。// 而0xF00反转过来就是0xF = 15,所以证明这个方法确实对15进行了反转。
3, Cfswapint16bigtohost ()
Convert a 16-bit integer number from big-endian to native data-storage mode. If the machine is in big-endian mode, the original value is unchanged.
// 把大端模式的数字Number转为本机数据存放模式CFSwapInt16BigToHost(Number)
4, Cfswapint32hosttobig ()
Converts a 32-bit native mode data to a big-endian mode. If the machine is in big-endian mode, the original value is unchanged.
// 把本地存储模式的数字Number转为大端模式CFSwapInt32HostToBig(Number)
There are a lot of ways (see official documentation) that are basically the same, and literally understand how it is used.
There are usually two or three of them that can be used.
The general requirement is to turn the big end into local mode, that is, the small terminal mode.
Cfswapint16bigtohost
Cfswapint32bigtohost
Here are the two encapsulated methods that can be used to parse data directly in development.
Two methods return data of type signed and unsigned, respectively.
The location in the code represents the position of the data to be parsed, and the offset represents the need to parse several.
* It is important to note that when it comes to parsing 1-bit data, you do not need to use a method like Cfswapint16bigtohost, which can be used to refer to the code.
Convert to local size end mode returns data of type signed + (Signedint) Signeddatatointwithdata: (NSData *) data location: (Nsinteger) Location Offset: (Nsinteger) Offset {Signedint value=0; NSData *intdata= [Data subdatawithrange:nsmakerange (location, offset)]; if (Offset==2) {value=cfswapint16bigtohost (* (int*) ([intdata bytes])); } else if (Offset==4) {value = Cfswapint32bigtohost (* (int*) ([intdata bytes]);} else if (Offset==1) {signed char *bs = (signed char *) [Data Subdatawithrange:nsmakerange (location, 1)] bytes]; value = *bs;} return value;}
Convert to local size end mode returns data of type unsigned + (Unsignedint) Unsigneddatatointwithdata: (NSData *) data location: (Nsinteger) Location Offset: (Nsinteger) Offset {Unsignedint value=0; NSData *intdata= [Data subdatawithrange:nsmakerange (location, offset)]; if (Offset==2) {value=cfswapint16bigtohost (* (int*) ([intdata bytes])); } else if (Offset==4) {value = Cfswapint32bigtohost (* (int*) ([intdata bytes]);} else if (Offset==1) {unsigned char *bs = (unsigned char *" [[Data Subdatawithrange:nsmakerange (location, 1)] bytes]; value = *bs;} return value;}
Third, bitwise operation, left SHIFT, right shift operation
Before explaining the bit operation and moving left and right, recall the basic unit of data measurement first.
1 bytes is a 8-bit data that can represent a total of 256 numbers from 0-255.
1B (Byte, byte) = 8 bit (bit).
Simulate the process of parsing data once:
If the data size of Bluetooth is 32 bytes each time, this data under the NSData type log out is like this: <0aa60000 00000000 00000000 00000000 00000000 00000059 9db56800 00260b01>
Each of the two numbers represents a hexadecimal data, such as the leftmost 0a represents a byte, which is 0x0a = 10.
Now we want to intercept the leftmost 0aa6 two bytes (16 bits), this data is the UInt16 type, then the first thing to do is to use the above encapsulated size-end conversion method to intercept the two bytes, the result in the following code is the required data.
// 从第0位开始,截取2个字节,所以location是0,offset是2UInt16 result = [self unsignedDataTointWithData:data Location:0 Offset:2];
But the work was not over after he got the result.
* Requirement: The binary of result is 0000 1010 1010 0110, a 16 digit number, if the hardware engineer agreed in advance, low 4 bits (0110) represent the number of groups, 5-8 bits (1010) represent the number of people per group.
How do you come up with the data you need separately?
This is where bitwise arithmetic comes in handy.
Take a look at the basic usage and scenarios of bitwise arithmetic and left and right shift, and the answer to the demand is in it.
1. Bitwise AND &
Same as 1 for 1, otherwise 0
Example: 3 & 5
0000 0011
0000 0101
0000 0001 = 1
So 3 & 5=1
Characteristics:
(1) Qing 0: Any number and 0 phase, the result is 0.
(2) Remove the value of the pointing position. Whichever one you take, set the corresponding bit to 1.
For example:
Got a 16-bit data result = 0000 1010 1010 0110, how to get the low 4 bits of this data?
You can use the bitwise-and code as follows
// 0x000f == 0000 0000 0000 1111// 按位与上result之后,得到的number == 0000 0000 0000 0110 就是低4位的数据0110int number = result & 0x000f;
2. Bitwise OR |
As long as one is 1, it's 1.
Negative numbers participate in a bitwise OR operation in the form of a complement
Example: 3 | 5
0000 0011
0000 0101
0000 0111 = 7
So 3 | 5=7
Characteristics:
(1) Some location of the data 1.
For example:
Will x=1010 0000 of the rear four positions 1
1010 0000
0000 1111
1010 1111
So the 4 digits are all 1.
3, XOR or operation ^
1 if the corresponding bit is different, same as 0
For example 3 ^ 5
0000 0011
0000 0101
0000 0110
So 3 ^ 5 = 6
Characteristics:
(1) Special positioning Flip, which one needs to flip the corresponding bit set to 1
(2) Any number and 0 XOR, the original value is unchanged.
(3) XOR operation can be exchanged position: 3 ^ 5 ^ 6 = = 3 ^ 6 ^ 5
(4) The same number is different or equal to 0:9 ^ 9 = = 0
(5) A ^ b ^ a = = B
4, Take counter ~
0 Change to 0
For example, ~
0000 0011
1111 1100
Characteristics:
(1) with bitwise and set the lowest bit of a number to 0
For example:
x=1011 0111 Bitwise AND (TO)
X & (To) = 1011 0110
So the last one is 0.
5. Left-shift Operation <<
Bits all left-shifted, left-side discarded, right-0
such as 3<<2
0000 0011 = 3
0000 1100 = 12 (after left shift)
Shift Left 3<<2 = = 12
Characteristics:
If the highest bit that is discarded when left shifts does not contain 1, each shift to the left is multiplied by 2.
So a<
6. Right Shift operation >>
Binary right shift several digits, positive left 0, negative left 1, right discard.
such as 12>>2
0000 1100 = 12
0000 0011 = 2 (after right shift)
Move Right 12>>2 = = 3
Characteristics:
Each right shift is divided by 2.
A>>n is the n-squared of a divided by 2.
For example:
Continue to use the above bitwise and example,
Got a 16-bit data result = 0000 1010 1010 0110, how do I get the 5-8 bits of this data?
First, use the bitwise and the 5-8-bit data all 0, and then move to the right to get the specific value.
The code is as follows
// 0x00f0 == 0000 0000 1111 0000,result按位与0xf0之后,结果为0000 0000 1010 0000// 然后右移4位,得到最终所需要的数据number == 0000 0000 0000 1010int number = (result & 0x00f0) >> 4;
iOS bluetooth communication data processing, bit arithmetic, data size end conversion