1

how hexadecimal string to Bytes and Bytes to hexadecimal string? I have oc code but I can not to write in swift can u help me ? thanks so much

+ (NSData *)convertHexToDataBytes:(NSString *)hexStr {
    NSMutableData *dataBytes = [NSMutableData data];
    int idx;
    for (idx = 0; idx + 2 <= hexStr.length; idx += 2) {
        NSRange range = NSMakeRange(idx, 2);
        NSString *singleHexStr = [hexStr substringWithRange:range];
        NSScanner *scanner = [NSScanner scannerWithString:singleHexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [dataBytes appendBytes:&intValue length:1];
    }
    return dataBytes;
}

+ (NSString *)convertDataBytesToHex:(NSData *)dataBytes {
    if (!dataBytes || [dataBytes length] == 0) {
        return @"";
    }
    NSMutableString *hexStr = [[NSMutableString alloc] initWithCapacity:[dataBytes length]];
    [dataBytes enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char *)bytes;
        for (NSInteger i = 0; i < byteRange.length; i ++) {
            NSString *singleHexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([singleHexStr length] == 2) {
                [hexStr appendString:singleHexStr];
            } else {
                [hexStr appendFormat:@"0%@", singleHexStr];
            }
        }
    }];
    return hexStr;
}

I write in swift like this

    class func convertHex(toDataBytes hexStr: String?) -> Data? {
        var dataBytes = Data()
        var idx: Int
        idx = 0
        while idx + 2 <= (hexStr?.count ?? 0) {
            let range = NSRange(location: idx, length: 2)
            let singleHexStr = (hexStr as NSString?)?.substring(with: range)
            let scanner = Scanner(string: singleHexStr ?? "")
            var intValue: UInt
            scanner.scanHexInt32(&UInt32(intValue))
            dataBytes.append(&intValue, count: 1)
            idx += 2
        }
        return dataBytes
    }

its error says:Cannot pass immutable value as inout argument: function call returns immutable value how to fix it?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
leeSin
  • 27
  • 1
  • 8
  • Are you asking how to translate this Objective-C code into Swift (off-topic) or are you asking about a problem with this Objective-C code? If the latter, then what is the problem? If the former, then post your attempted Swift code and explain your issues. – rmaddy Apr 24 '19 at 07:39
  • @rmaddy i edit it again, I do not konw how to fix its error – leeSin Apr 24 '19 at 07:56
  • Possibly helpful: [hex/binary string conversion in Swift](https://stackoverflow.com/questions/40276322/hex-binary-string-conversion-in-swift). – Martin R Apr 24 '19 at 08:08
  • @MartinR its userful thanks~~~~ – leeSin Apr 24 '19 at 08:25

1 Answers1

0

To answer your immediate question: UInt32(intValue) creates a new (constant) value whose address cannot be taken with &. So

var intValue: UInt
scanner.scanHexInt32(&UInt32(intValue))

should be

var intValue: UInt32 = 0
scanner.scanHexInt32(&intValue)

And

dataBytes.append(&intValue, count: 1)

does not compile because &intValue is a pointer to an integer, not to an UInt8. Here you can do

dataBytes.append(UInt8(intValue))

because the value is known to fit in a single byte.

Having said that, all the conversions from String to NSString are not needed. A more “Swifty” translation of that Objective-C code to Swift would be

func convertHex(toDataBytes hexStr: String) -> Data {
    var dataBytes = Data()
    var startPos = hexStr.startIndex
    while let endPos = hexStr.index(startPos, offsetBy: 2, limitedBy: hexStr.endIndex) {
        let singleHexStr = hexStr[startPos..<endPos]
        let scanner = Scanner(string: String(singleHexStr))
        var intValue: UInt32 = 0
        scanner.scanHexInt32(&intValue)
        dataBytes.append(UInt8(intValue))
        startPos = endPos
    }
    return dataBytes
}

For an alternative approach (which includes error checking) see for example hex/binary string conversion in Swift

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382