iOS Objective-C 工具类:数据转换工具 ParseDataTool 解析

在iOS开发中,我们常常需要对十六进制、二进制字符串、NSData、整数、字节序等数据类型进行转换与处理,尤其在与硬件通信(如蓝牙BLE、WIFI)、网络协议、加密等场景中使用频繁。

本文将介绍一个我在iOS开发过程中通用且实用的 Objective-C 工具类 ------ ParseDataTool,它封装了常见的数据转换逻辑,并提供了清晰的 API 接口,方便项目中直接使用。

工具类简介

该工具类主要功能如下:

  • 十六进制字符串与 NSData、整数之间的互相转换
  • 大端、小端字节序处理
  • 十六进制字符串格式化显示(方便打印调试)
  • 异或计算校验
  • NSData 安全裁剪,防止越界崩溃
  • 字节反转(适用于小端传输转大端展示)

工具类接口头文件(ParseDataTool.h)

js 复制代码
//
//  ParseDataTool.h
//  数据转换工具类
//
//  Created by tangbin on 2025/01/03.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

/// 数据转换工具类
@interface ParseDataTool : NSObject

/// 小端NSData转整数
+ (NSInteger)transLittleEndianDataToInteger:(NSData *)data;

/// 大端NSData转整数
+ (NSInteger)convertDataToInteger:(NSData *)data;

/// NSData 转十六进制字符串
+ (NSString *)transDataToHexString:(NSData *)data;

/// 十六进制字符串转 NSData
+ (NSData *)transToDataWithString:(NSString *)hexString;

/// 十六进制字符串倒序排列
+ (NSString *)invertedOrderWithStr:(NSString *)str;

/// 十六进制字符串转十进制整数
+ (NSInteger)convertToDecimalFromHex:(NSString *)hexString;

/// 格式化为 "aa bb cc dd"
+ (NSString *)describeBlankFormatWithString:(NSString *)dataString;

/// 格式化为 "0xaa, 0xbb, 0xcc, 0xdd"
+ (NSString *)describeBytesFormatWithString:(NSString *)dataString;

/// 字节序转换:小端 <-> 大端
+ (NSData *)convertNSData:(NSData *)source;

/// 将字符串按大端字节序排列(默认倒序)
+ (NSString *)transString2BigMode:(NSString *)string;

/// 字节异或校验值(返回字符串)
+ (NSString *)xorWithDataString:(NSString *)dataString;

/// 比较 NSData 异或校验结果是否为某个值
+ (BOOL)compareImageData:(NSData *)imageData withXORValue:(NSInteger)xorValue;

/// 安全截取NSData(越界不会崩溃)
+ (NSData *)subMyData:(NSData *)data range:(NSRange)range;

/// 长度交换:16位数(用于字节反转)
+ (UInt16)numswap:(int)len;

@end

NS_ASSUME_NONNULL_END

工具类实现文件(ParseDataTool.m)

js 复制代码
//
//  ParseDataTool.m
//  数据转换工具类
//
//  Created by tangbin on 2025/01/03.
//

#import "ParseDataTool.h"

@implementation ParseDataTool

#pragma mark - 十六进制与整数转换

+ (NSInteger)transLittleEndianDataToInteger:(NSData *)data {
    if (!data || data.length == 0) return 0;
    UInt32 value = 0;
    [data getBytes:&value length:MIN(sizeof(value), data.length)];
    return CFSwapInt32LittleToHost(value);
}

+ (NSInteger)convertDataToInteger:(NSData *)data {
    if (!data || data.length == 0) return 0;
    UInt32 value = 0;
    [data getBytes:&value length:MIN(sizeof(value), data.length)];
    return CFSwapInt32BigToHost(value);
}

#pragma mark - 十六进制与字符串转换

+ (NSString *)transDataToHexString:(NSData *)data {
    if (!data || data.length == 0) return @"";
    const unsigned char *dataBuffer = data.bytes;
    NSMutableString *hexString = [NSMutableString stringWithCapacity:data.length * 2];
    for (int i = 0; i < data.length; ++i) {
        [hexString appendFormat:@"%02x", dataBuffer[i]];
    }
    return [hexString copy];
}

+ (NSData *)transToDataWithString:(NSString *)hexString {
    if (!hexString || hexString.length == 0) return [NSData data];
    NSMutableData *data = [NSMutableData data];
    NSString *cleanString = [hexString stringByReplacingOccurrencesOfString:@" " withString:@""];
    for (NSInteger i = 0; i < cleanString.length; i += 2) {
        NSString *byteString = [cleanString substringWithRange:NSMakeRange(i, 2)];
        unsigned int byteValue = 0;
        [[NSScanner scannerWithString:byteString] scanHexInt:&byteValue];
        UInt8 byte = (UInt8)byteValue;
        [data appendBytes:&byte length:1];
    }
    return [data copy];
}

+ (NSString *)invertedOrderWithStr:(NSString *)str {
    if (!str || str.length % 2 != 0) return @"";
    NSMutableString *result = [NSMutableString string];
    for (NSInteger i = str.length; i > 0; i -= 2) {
        NSString *byte = [str substringWithRange:NSMakeRange(i - 2, 2)];
        [result appendString:byte];
    }
    return [result copy];
}

+ (NSInteger)convertToDecimalFromHex:(NSString *)hexString {
    if (!hexString || hexString.length == 0) return 0;
    unsigned int result = 0;
    [[NSScanner scannerWithString:hexString] scanHexInt:&result];
    return result;
}

#pragma mark - 格式化输出辅助

+ (NSString *)describeBlankFormatWithString:(NSString *)dataString {
    if (!dataString || dataString.length == 0) return @"";
    NSMutableArray *components = [NSMutableArray array];
    for (NSInteger i = 0; i < dataString.length; i += 2) {
        if (i + 2 <= dataString.length) {
            NSString *byte = [dataString substringWithRange:NSMakeRange(i, 2)];
            [components addObject:byte];
        }
    }
    return [components componentsJoinedByString:@" "];
}

+ (NSString *)describeBytesFormatWithString:(NSString *)dataString {
    if (!dataString || dataString.length == 0) return @"";
    NSMutableArray *components = [NSMutableArray array];
    for (NSInteger i = 0; i < dataString.length; i += 2) {
        if (i + 2 <= dataString.length) {
            NSString *byte = [dataString substringWithRange:NSMakeRange(i, 2)];
            [components addObject:[NSString stringWithFormat:@"0x%@", byte]];
        }
    }
    return [components componentsJoinedByString:@", "];
}

#pragma mark - 大小端与字符串处理

+ (NSString *)transString2BigMode:(NSString *)string {
    // 默认假设为小端,按两位进行倒序
    return [self invertedOrderWithStr:string];
}

+ (NSData *)convertNSData:(NSData *)source {
    if (!source || source.length == 0) return [NSData data];
    NSMutableData *result = [NSMutableData dataWithCapacity:source.length];
    const Byte *srcBytes = source.bytes;
    for (NSInteger i = source.length - 1; i >= 0; i--) {
        [result appendBytes:&srcBytes[i] length:1];
    }
    return [result copy];
}

+ (UInt16)numswap:(int)len {
    UInt16 value = (UInt16)len;
    return (value >> 8) | (value << 8);
}

#pragma mark - 异或计算与校验

+ (NSString *)xorWithDataString:(NSString *)dataString {
    if (!dataString || dataString.length % 2 != 0) return @"00";
    UInt8 xorResult = 0x00;
    for (NSInteger i = 0; i < dataString.length; i += 2) {
        NSString *byteStr = [dataString substringWithRange:NSMakeRange(i, 2)];
        unsigned int byte = 0;
        [[NSScanner scannerWithString:byteStr] scanHexInt:&byte];
        xorResult ^= (UInt8)byte;
    }
    return [NSString stringWithFormat:@"%02x", xorResult];
}

+ (BOOL)compareImageData:(NSData *)imageData withXORValue:(NSInteger)xorValue {
    if (!imageData || imageData.length == 0) return NO;
    UInt8 result = 0x00;
    const Byte *bytes = imageData.bytes;
    for (NSInteger i = 0; i < imageData.length; i++) {
        result ^= bytes[i];
    }
    return result == xorValue;
}

#pragma mark - 安全的数据裁剪

+ (NSData *)subMyData:(NSData *)data range:(NSRange)range {
    if (!data || data.length == 0) return [NSData data];
    if (range.location + range.length > data.length) return [NSData data];
    return [data subdataWithRange:range];
}

@end

工具类适用场景

  • BLE蓝牙设备通信(特征值读写、帧协议解析)
  • 自定义数据加密与解密
  • 十六进制计算与打印调试
  • 文件与图片二进制数据分析
  • 网络数据传输中的底层数据封装/解析

代码延伸

  • 大小端模式:iOS 是基于大端的架构,但许多硬件设备采用小端,处理时需注意。
  • NSData 安全性 :不使用越界的 subdataWithRange:,避免运行时崩溃。
  • 异或校验:常用于通信协议中的数据完整性校验,快速但不适合高安全场景。

最后

在实际开发中非常实用的 Objective-C 工具类 ParseDataTool,它封装了常见的二进制数据处理方法,可直接用于 iOS 项目开发,也适合作为学习字节、编码、异或等底层知识的参考工具类。如有写错的地方欢迎各位不吝赐教,谢谢大家。

相关推荐
itme2681 天前
解决cocos 2dx/creator2.4在ios18下openURL无法调用的问题
macos·objective-c·cocoa
qq_279456151 天前
CADisplayLink、NSTimer、GCD定时器
macos·objective-c·cocoa
键盘敲没电2 天前
【IOS】GCD学习
学习·ios·objective-c·xcode
豪冷啊4 天前
iOS UIActivityViewController 组头处理
ios·objective-c·xcode
键盘敲没电5 天前
【iOS】多线程基础
学习·macos·ios·objective-c·cocoa
hbysjw6 天前
ios tableview吸顶
ios·objective-c
一丝晨光7 天前
Windows搭建Swift语言编译环境?如何构建ObjC语言编译环境?Swift如何引入ObjC框架?Interface Builder的历史?
linux·windows·macos·ios·objective-c·xcode·swift
他们都不看好你,偏偏你最不争气7 天前
iOS —— UI 初探
开发语言·macos·ui·ios·objective-c·面向对象
键盘敲没电8 天前
【iOS】方法交换
学习·macos·ios·objective-c·cocoa