This is what I have so far, but it doesn't seem to match http://zorc.breitbandkatze.de/crc.html all the time.
short crcTable[256];
for (int i = 0; i < 256; i++) {
int crc = (i << 4);
for (int j = 0; j < 8; j++) {
crc = (crc << 1) ^ ((crc & 0x800) ? 0x80F : 0);
}
crcTable[i] = crc & 0xFFF;
}
NSString *theString = #"blah";
unsigned char *string = (unsigned char *)[theString UTF8String];
int length = [theString length];
unsigned short crc = 0;
for (int i = 0; i < length; i++) {
crc = crcTable[(crc ^ string[i]) & 255] ^ (crc >> 8);
}
NSLog(#"%X", crc);
One of our implementations is incorrect, I'm assuming it's mine. But I have no idea what's wrong, or really how to go about working out what's wrong. Any help'd be much appreciated.
Alec
1 Replace
crc = crcTable[(crc ^ string[i]) & 255] ^ (crc >> 8);
by
crc = crcTable[(crc >> 4) ^ string[i]] ^ (crc << 8);
2 Do mirror the 8 bits of each of the message's bytes before using them to calculate the crc value.
3 Finally mirror the 12 bits of the final crc.
As an alternative to the last mod you could also just do a crc & 0xfff and tell the breitbandkatze to 'reverse data bytes'.
You will want to double check, but it appears you are building your table with big-endian code and calculating your CRC with little-endian code.
Try replacing this:
crc = crcTable[(crc ^ string[i]) & 255] ^ (crc >> 8);
with this:
crc = crc ^ (string[i] << 4);
crc = (crcTable[(crc >> 4) & 0xFF] ^ (crc << 4)) & 0xFFF;
-Jesse
Related
I have this piece of Objective-C code and I'm breaking my had as to how to write this in Swift instead:
NSData *data = [NSData data];
char vals[value.length];
[value getBytes:vals length:value.length];
Point3D aPoint;
aPoint.x = ((float)((int16_t)((vals[0] & 0xff) | (((int16_t)vals[1] << 8) & 0xff00)))/ (float) 32768) * 255 * 1;
aPoint.y = ((float)((int16_t)((vals[2] & 0xff) | (((int16_t)vals[3] << 8) & 0xff00)))/ (float) 32768) * 255 * 1;
aPoint.z = ((float)((int16_t)((vals[4] & 0xff) | (((int16_t)vals[5] << 8) & 0xff00)))/ (float) 32768) * 255 * 1;
I've tried using this:
let data: NSData = NSData(data: characteristic.value!)
var vals = [CChar16](repeating: CChar16(), count: data.length)
but that only resulted in:
Cannot subscript a value of type 'inout [CChar16]' (aka 'inout
Array')
any help would be greatly appreciated.
i am new to iOS i need to create data packet by using CRC algorithm for the below commands
int comm[6];
comm[0]=0x01;
comm[1]=6;
comm[2]=0x70;
comm[3]=0x00;
comm[4]=0xFFFF;
comm[5]=0xFFFF;
i had a java code which as same thing developing in android
byte[] getCRC(byte[] bytes)
{
byte[] result = new byte[2];
try
{
short crc = (short) 0xFFFF;
for (int j = 0; j < bytes.length; j++)
{
byte c = bytes[j];
for (int i = 7; i >= 0; i--)
{
boolean c15 = ((crc >> 15 & 1) == 1)
boolean bit = ((c >> (7 - i) & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
{
crc ^= 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
}
}
}
int crc2 = crc - 0xffff0000;
result[0] = (byte) (crc2 % 256);
result[1] = (byte) (crc2 / 256);
return result;
}
catch(Exception ex)
{
result = null;
return result;
}
}
Input for getCRC() method: The data packet for which CRC is to be calculated.
Output of getCRC() method: CRC for the packet.
The same thing i need to do in obj c please help if any sample code available also.
Objective-C also incorporates C, so the contents of your method will look almost the same as in Java. All that is needed is to pass your data into and out of the method, in this example using NSData:
- (NSData *)bytesCRCResult:(NSData *)dataBytes
{
unsigned char *result = (unsigned char *)malloc(2);
unsigned char *bytes = (unsigned char *)[dataBytes bytes]; // returns readonly pointer to the byte stream
uint16_t crc = (short) 0xFFFF;
for (int j = 0; j < dataBytes.length; j++)
{
unsigned char c = bytes[j];
for (int i = 7; i >= 0; i--)
{
bool c15 = ((crc >> 15 & 1) == 1);
bool bit = ((c >> (7 - i) & 1) == 1);
crc <<= 1;
if (c15 ^ bit)
{
crc ^= 0x1021; // 0001 0000 0010 0001 (0, 5, 12)
}
}
}
uint16_t crc2 = crc - 0xffff0000;
result[0] = (unsigned char) (crc2 % 256);
result[1] = (unsigned char) (crc2 / 256);
NSData *resultsToData = [NSData dataWithBytes:result length:2];
free(result);
return resultsToData;
}
NSData can be read as raw bytes using the [NSData bytes] method call, and has a range of useful properties and methods.
For the boolean value, you have a few options:
"bool" seems to be the ISO C/C++ standard type
"Boolean" is defined as "typedef unsigned char"
"boolean_t" is defined as "typedef unsigned int" or "typedef int", depending on 64-bit compilation apparently
"BOOL", the Objective-C bool, which is defined as "typedef signed char", according to http://nshipster.com/bool/ and might therefore not behave as expected.
"uint8_t" can be substituted for "unsigned char", for clarity.
Please note: The above code compiles without warning or complaint, but wasn't tested with actual data.
Need to generated some random 10 byte length string in c function and call the function from objective-c. So, I'm creating a pointer to uint8_t and passing it to C function. The function generates random bytes and assigns them to *randomString. However, after returning from function to objective-c randomValue pointer points to NULL.
Here's my random function in C:
void randomString(uint8_t *randomString)
{
randomString = malloc(10);
char randomByte;
char i;
for (i = 0; i < 10; i++) {
srand((unsigned)time(NULL));
randomByte = (rand() % 255 ) + 1;
*randomString = randomByte;
randomString++;
}
}
Here's objective-c part:
uint8_t *randomValue = NULL;
randomString(randomValue); //randomValue points to 0x000000
NSString *randomString = [[NSString alloc] initWithBytes:randomValue length:10 encoding:NSASCIIStringEncoding];
NSLog(#"Random string: %#", randomString);
A more natural semantic, like malloc() itself would be:
uint8_t * randomString()
{
uint8_t *randomString = malloc(10);
srand((unsigned)time(NULL));
for (unsigned i = 0; i < 10; i++)
randomString[i] = (rand() % 254) + 1;
return randomString;
}
Pointers are passed by value, so randomValue will remain NULL after the call of randomString. You need to pass a pointer to a pointer in order to make it work:
void randomString(uint8_t **randomString) {
*randomString = malloc(10);
// ... the rest of your code goes here, with an extra level of indirection
}
uint8_t *randomValue = NULL;
randomString(&randomValue);
You probably should be using uint8_t **randomeValue instead of uint8_t *.
I'm getting a NSData * and trying to get it byte by byte but the data is filled with f.
NSData *Data = getData();
cout << "The log way:" << endl;
NSLog(#"%#", Data);
cout << "The data way:" << endl;
char *data = (char *)[Data bytes];
for(int i = 0; i < [Data length]; i++)
{
cout.width(2);
cout.fill(0);
cout << hex << (int)(data[i]) << " ";
}
cout << endl;
What I'm getting as output:
The log way:
/* something long about time and file */<1f9cb0f8>
The data way:
1f ffffff9c ffffffb0 fffffff8
How can I get this data as ints without all those f?
The char data type is of undefined signedness, and it seems your compiler (gcc or clang?) decided it should be signed. Therefore, when you cast a char to a larger type, sign extension is used, which fills the extra bits with the same value the most significant bit has. For bytes with a value larger than 0x7F, the most significant bit is set, so it breaks the enlargement.
What you want is zero extension, which zeroes the extra bits. You can get it by using the unsigned char type.
This should do it:
unsigned char *data = (unsigned char *)[Data bytes];
By the way, -[NSData bytes] return a const pointer. You should honor this and mark your pointer as const too:
const unsigned char *data = (const unsigned char *)[Data bytes];
That is data as ints, sort of. The data is split into bytes and sign-extended to ints. As bytes, your data is 1f 9c b0 f8. 9c, b0, and f8 are all negative, so they are sign extended by making the extra bits all 1, which is why you are getting a bunch of fs.
How do I read the image color information for each pixel of PVRTC image?
Here is my code extracting the integer arrays
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSMutableArray *_imageData = [[NSMutableArray alloc] initWithCapacity:10];
BOOL success = FALSE;
PVRTexHeader *header = NULL;
uint32_t flags, pvrTag;
uint32_t dataLength = 0, dataOffset = 0, dataSize = 0;
uint32_t blockSize = 0, widthBlocks = 0, heightBlocks = 0;
uint32_t width = 0, height = 0, bpp = 4;
uint8_t *bytes = NULL;
uint32_t formatFlags;
header = (PVRTexHeader *)[data bytes];
pvrTag = CFSwapInt32LittleToHost(header->pvrTag);
if (gPVRTexIdentifier[0] != ((pvrTag >> 0) & 0xff) ||
gPVRTexIdentifier[1] != ((pvrTag >> 8) & 0xff) ||
gPVRTexIdentifier[2] != ((pvrTag >> 16) & 0xff) ||
gPVRTexIdentifier[3] != ((pvrTag >> 24) & 0xff))
{
return FALSE;
}
flags = CFSwapInt32LittleToHost(header->flags);
formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
if (formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2)
{
[_imageData removeAllObjects];
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
else if (formatFlags == kPVRTextureFlagTypePVRTC_2)
_internalFormat = GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
_width = width = CFSwapInt32LittleToHost(header->width);
_height = height = CFSwapInt32LittleToHost(header->height);
if (CFSwapInt32LittleToHost(header->bitmaskAlpha))
_hasAlpha = TRUE;
else
_hasAlpha = FALSE;
dataLength = CFSwapInt32LittleToHost(header->dataLength);
bytes = ((uint8_t *)[data bytes]) + sizeof(PVRTexHeader);
// Calculate the data size for each texture level and respect the minimum number of blocks
while (dataOffset < dataLength)
{
if (formatFlags == kPVRTextureFlagTypePVRTC_4)
{
blockSize = 4 * 4; // Pixel by pixel block size for 4bpp
widthBlocks = width / 4;
heightBlocks = height / 4;
bpp = 4;
}
else
{
blockSize = 8 * 4; // Pixel by pixel block size for 2bpp
widthBlocks = width / 8;
heightBlocks = height / 4;
bpp = 2;
}
// Clamp to minimum number of blocks
if (widthBlocks < 2)
widthBlocks = 2;
if (heightBlocks < 2)
heightBlocks = 2;
dataSize = widthBlocks * heightBlocks * ((blockSize * bpp) / 8);
[_imageData addObject:[NSData dataWithBytes:bytes+dataOffset length:dataSize]];
for (int i=0; i < mipmapCount; i++)
{
NSLog(#"width:%d, height:%d",width,height);
data = [[NSData alloc] initWithData:[_imageData objectAtIndex:i]];
NSLog(#"data length:%d",[data length]);
//extracted 20 sample data, but all u could see are large integer number
for(int i = 0; i < 20; i++){
NSLog(#"data[%d]:%d",i,data[i]);
}
PVRTC is a 4x4 (or 8x4) texel, block-based compression system that takes into account surrounding blocks to represent two low frequency images with which higher frequency modulation data is combined in order to produce the actual texel output. A better explanation is available here:
http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf
So the values you're extracting are actually parts of the encoded blocks and these need to be decoded correctly in order to get sensible values.
There are two ways to get to the colour information: decode/decompress the PVR texture information using a software decompressor or render the texture using a POWERVR graphics core and then read the result back. I'll only discuss the first option here.
It's rather tricky to assemble a decompressor from only the information there, but fortunately there's C++ decompression source code in the POWERVR SDK which you can get here - download one of the iPhone SDKs for instance:
http://www.imgtec.com/powervr/insider/powervr-sdk.asp
It's in the Tools/PVRTDecompress.cpp file.
Hope that helps.