How to Use Crc32 from Zlib in Swift (Xcode 9)

How do I hash key and secret message in crc32 using Python hashlib or zlib?

You can simply concatenate key and secret and use zlib.crc32() to compute the CRC-32 of that sequence of bytes.

However, are you sure that's what you want? There's a reason that hashlib does not have a CRC-32, which is that it is easy to spoof. I.e., come up with different data that has the same hash.

How To Generate SHA256 and CRC32 in ios

SHA256 is available in CommonCrypto. CRC32 is not a hash, it a Cyclic Redundancy Check.

Example code:

#import <CommonCrypto/CommonDigest.h>

NSData *dataIn = [@"Now is the time for all good computers to come to the aid of their masters." dataUsingEncoding:NSASCIIStringEncoding];
NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];

CC_SHA256(dataIn.bytes, dataIn.length, macOut.mutableBytes);

NSLog(@"dataIn: %@", dataIn);
NSLog(@"macOut: %@", macOut);

NSLog output:

dataIn: <4e6f7720 69732074 68652074 696d6520 666f7220 616c6c20 676f6f64 20636f6d 70757465 72732074 6f20636f 6d652074 6f207468 65206169 64206f66 20746865 6972206d 61737465 72732e>

macOut: <53f89cf6 7ebfbe56 89f1f76a 3843dfd1 09d68c5b a938dcd2 9a12004e 108260cb>

How to properly use carry-less multiplication assembly (PCLMULQDQ) in zlib CRC32?

As it says, you need to calculate the CRC sum on a 16-byte aligned buffer that has length of multiple of 16 bytes. Thus you'd cast the current buffer pointer as uintptr_t and for as long as its 4 LSB bits are not zero, you increase the pointer feeding the bytes into an ordinary CRC-32 routine. Once you've at 16-byte aligned address, you round the remaining length down to multiple of 16, then feed these bytes to the fast CRC-32, and again the remaining bytes to the slow calculation.


Something like:

// a function for adding a single byte to crc
uint32_t crc32_by_byte(uint32_t crc, uint8_t byte);

// the assembly routine
uint32_t _crc32_vec(uint32_t crc, uint8_t *input, int length);

uint32_t crc = initial_value;
uint8_t *input = whatever;
int length = whatever; // yes, the assembly uses *int* length.

assert(length >= 32); // if length is less than 32 just calculate byte by byte
while ((uintptr_t)input & 0xf) { // for as long as input is not 16-byte aligned
crc = crc32_by_byte(crc, *input++);
length--;
}

// input is now 16-byte-aligned
// floor length to multiple of 16
int fast_length = (length >> 4) << 4;
crc = _crc32_vec(crc, input, fast_length);

// do the remaining bytes
length -= fast_length;
while (length--) {
crc = crc32_by_byte(crc, *input++)
}
return crc;

How to convert an Obj-C method with NSData bytes using bitwise operators to Swift

Instead of writing the implementation from scratch, why don't you use the zlib implementation of crc32?:

import zlib

func crc32(from data: Data) -> UInt {
return data.withUnsafeBytes { (buffer: UnsafePointer<Bytef>) -> UInt in
return zlib.crc32(0, buffer, uInt(data.count))
}
}

However, to help you understand the bitwise operations:

func computeCRC(message: [UInt8]) -> UInt32 {
var crc: UInt32 = 0xFFFFFFFF

for byte in message {
crc ^= UInt32(byte)
for _ in 0 ..< 8 {
// negation using 2-complement: -x = ~x + 1
// use &+ addition with overflow
let mask = ~(crc & 1) &+ 1
crc = (crc >> 1) ^ (0xEDB88320 & mask)
}
}

return ~crc
}

Note that we don't need to pass the number of bytes in Swift. The implementations have different signatures and return a slightly different type but they both give the same result.

Compression API on the iPhone

zlib and bzip2 are available. And you can always add others, as long as they'll (generally) compile under OS X.

bzip2 is a better choice for smallest file sizes, but requires much more CPU power to compress and decompress.

Also, since you're talking to a web service, you may not have to do much. NSURLRequest accepts gzip encoding transparently in server responses.



Related Topics



Leave a reply



Submit