Преобразование NSData в int
У меня есть объект NSData, длина 4 байта. Эти четыре байта я извлекаю из другого объекта NSData, используя
fourByteData=[completeData subdataWithRange:NSMakeRange(0, 16)];
Мой первый вопрос: будет ли приведенный выше оператор предоставить мне первые четыре байта полных данных.
Если да, то как преобразовать все эти байты в эквивалентный int.
Ответы
Ответ 1
Является ли 268566528 ценность, которую вы ожидаете, или, возможно, вы ожидаете 528? Если правильное значение равно 528, тогда порядок байтов является big-endian, но cpu является малоприводным, байты должны быть отменены.
Итак, если правильное значение должно быть 528, то:
NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32BigToHost(*(int*)([data4 bytes]));
Также обратите внимание, что стандартный сетевой порядок является большим.
Ответ 2
Этот оператор предоставит вам первые 16 байтов данных, а не 4. Чтобы получить первые 4 байта, вам нужно изменить свой оператор на:
fourByteData = [completeData subdataWithRange:NSMakeRange(0, 4)];
Чтобы прочитать данные из объекта NSData в целое число, вы можете сделать что-то вроде:
int theInteger;
[completeData getBytes:&theInteger length:sizeof(theInteger)];
Вам не нужно получать первые 4 байта, если вы просто конвертируете его в целое. Вы можете сделать это непосредственно из двух строк выше и вашего приемника completeData
Ответ 3
Нет, вы получите 16 байт данных, так как диапазон от смещения 0, а затем 16 байт.
Если у вас был экземпляр NSData
с 4 байтами, вы можете сделать простой тип, например:
int value = *(int*)([data bytes]);
Ответ 4
- (unsigned)parseIntFromData:(NSData *)data{
NSString *dataDescription = [data description];
NSString *dataAsString = [dataDescription substringWithRange:NSMakeRange(1, [dataDescription length]-2)];
unsigned intData = 0;
NSScanner *scanner = [NSScanner scannerWithString:dataAsString];
[scanner scanHexInt:&intData];
return intData;
}
int numberOfChunks = [self parseIntFromData:data];
Ответ 5
iOS integer хранит LSB (младший значащий байт) в первом байте и MSB в последнем байте. У меня есть процедура преобразования, чтобы проверить все эти вещи. здесь,
Тест...
int i = 2342342;
NSData * d1 = [Util dataFromInt:i]; // {[MSB], ..., ... ,[LSB]} <0023bdc6>
NSData * d2 = [NSData dataWithBytes:&i length:4]; // {[LSB], ..., ... ,[MSB]} <c6bd2300>
int ci1 = [Util intFromData:d1];
int ci2 = [Util intFromDataReverse:d2];
Util.m
+ (NSData *) dataFromInt:(int)num {
unsigned char * arr = (unsigned char *) malloc(sizeof(num) * sizeof(unsigned char));
for (int i = sizeof(num) - 1 ; i >= 0; i --) {
arr[i] = num & 0xFF;
num = num >> 8;
}
NSData * data = [NSData dataWithBytes:arr length:sizeof(num)];
free(arr);
return data;
}
// {[MSB], ..., ... ,[LSB]}
+ (int) intFromData:(NSData *)data
{
int intSize = sizeof(int); // change it to fixe length
unsigned char * buffer = malloc(intSize * sizeof(unsigned char));
[data getBytes:buffer length:intSize];
int num = 0;
for (int i = 0; i < intSize; i++) {
num = (num << 8) + buffer[i];
}
free(buffer);
return num;
}
// {[LSB], ..., ... ,[MSB]}
+ (int) intFromDataReverse:(NSData *)data
{
int intSize = sizeof(int);// change it to fixe length
unsigned char * buffer = malloc(intSize * sizeof(unsigned char));
[data getBytes:buffer length:intSize];
int num = 0;
for (int i = intSize - 1; i >= 0; i--) {
num = (num << 8) + buffer[i];
}
free(buffer);
return num;
}
Ответ 6
Это зависит от нотации Endianness данных, которые вы хотите преобразовать, в отношении нотации устройства.
wiki для Endianness
Чтобы это было просто, вам нужно проверить, есть ли два метода
NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32BigToHost(*(int*)([data4 bytes]));
или
NSData *data4 = [completeData subdataWithRange:NSMakeRange(0, 4)];
int value = CFSwapInt32LittleToHost(*(int*)([data4 bytes]));
И проверьте, какой из них имеет смысл при анализе данных.