ios - How to calculate CRC-8-Dallas/Maxim of NSData? - ios

I need to calculate exactly CRC-8-Dallas/Maxim. Can someone provide an algorithm?
Any help is appreciated!

CRC-8-Dallas/Maxim Variant 1 (C style):
unsigned char dallas_crc8(const unsigned char * data, const unsigned int size)
{
unsigned char crc = 0;
for ( unsigned int i = 0; i < size; ++i )
{
unsigned char inbyte = data[i];
for ( unsigned char j = 0; j < 8; ++j )
{
unsigned char mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if ( mix ) crc ^= 0x8C;
inbyte >>= 1;
}
}
return crc;
}
CRC-8-Dallas/Maxim Variant 2 (C style):
unsigned char crc_bits(unsigned char data)
{
unsigned char crc = 0;
if(data & 1) crc ^= 0x5e;
if(data & 2) crc ^= 0xbc;
if(data & 4) crc ^= 0x61;
if(data & 8) crc ^= 0xc2;
if(data & 0x10) crc ^= 0x9d;
if(data & 0x20) crc ^= 0x23;
if(data & 0x40) crc ^= 0x46;
if(data & 0x80) crc ^= 0x8c;
return crc;
}
unsigned char dallas_crc8(const unsigned char * data, const unsigned int size)
{
unsigned char crc = 0;
for ( unsigned int i = 0; i < size; ++i )
{
crc = crc_bits(data[i] ^ crc);
}
return crc;
}
CRC-8-Dallas/Maxim Variant 3 (C style):
unsigned char crc_array[256] =
{
0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41,
0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc,
0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62,
0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5,
0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6,
0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24,
0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9,
0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f,
0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50,
0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c,
0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee,
0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1,
0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73,
0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16,
0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a,
0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8,
0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
};
unsigned char dallas_crc8(const unsigned char * data, const unsigned int size)
{
unsigned char crc = 0;
for ( unsigned int i = 0; i < size; ++i )
{
crc = crc_array[data[i] ^ crc];
}
return crc;
}
CRC-8-Dallas/Maxim Variant 4 (C++ style with boost):
#include "boost/crc.hpp"
uint8_t dallas_crc8(const uint8_t * data, const uint32_t size)
{
boost::crc_optimal <8, 0x31, 0, 0, true, true> crc;
crc.process_bytes(data, size);
return crc.checksum();
}

#define CRC8INIT 0x00
#define CRC8POLY 0x31 // = X^8+X^5+X^4+X^0
uint8_t crc8(uint8_t *data, uint16_t size)
{
uint8_t crc, i;
crc = CRC8INIT;
while (size--)
{
crc ^= *data++;
for (i = 0; i < 8; i++)
{
if (crc & 0x80) crc = (crc << 1) ^ CRC8POLY;
else crc <<= 1;
}
}
return crc;
}

Based on Stamen Rakov answer, here is the variant 1 function in Go style:
func dallas_crc8(data []uint8) uint8 {
var crc uint8 = 0;
for _, inbyte := range data {
for j := 0; j < 8; j++ {
mix := (crc ^ inbyte) & 0x01
crc >>= 1;
if mix > 0 {
crc ^= 0x8C
}
inbyte >>= 1
}
}
return crc
}

Related

UInt8 from Swift to Objective-C

I need a clarification. I'm following a tutorial on Hash sha256 in Swift and my app is in Objective-C. I have trouble translating this UInt8 in Objective-C. What is the equivalent in Objective-C?
let rsa2048Asn1Header:[UInt8] = [
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
]
I tried this but I'm not sure it's right I'd like to have confirmation
UInt8 rsa2048AsnlHeader[] = {
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
Yes what you posted above would work if you're just looking to use a primitive array in Objective-C.
Another option would be to use NSArray, shown below:
NSArray<NSNumber *> *rsa2048AsnlHeader = #[
#0x30, #0x82, #0x01, #0x22, #0x30, #0x0d, #0x06, #0x09, #0x2a, #0x86, #0x48, #0x86,
#0xf7, #0x0d, #0x01, #0x01, #0x01, #0x05, #0x00, #0x03, #0x82, #0x01, #0x0f, #0x00
];
To get the equivalent UInt8 value from the NSNumber elements, use the unsignedCharValue property of the NSNumber class (which is equivalent to uint8Value in Swift). For example:
for (NSNumber *value in rsa2048AsnlHeader) {
UInt8 uint8Value = value.unsignedCharValue;
// ...
}
Source

How to store and retrieve byte array [UInt8] into sqlite3 database using BLOB in swift?

let arr: [UInt8] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15, 0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 0x20, 0x20, 0x20, 0x00]
How can i store in sqlite3 or in NSUserDefaults
i have tried like this
let arrData = NSData(bytes: &arr, length: (arr?.count)!)
let d = NSUserDefaults.standardUserDefaults()
d.setObject(arrData, forKey: "mydata")
d.synchronize()
let obj = d.objectForKey("mydata")
let objData = obj as! NSData
let resultArr = NSKeyedUnarchiver.unarchiveObjectWithData(objData) as! [UInt8]
print(resultArr.count)
For NSUserDefaults:
let integersToStore: [UInt8] = [0x14, 0x00, 0xAB, 0x45, 0x49, 0x1F, 0xEF, 0x15, 0xA8, 0x89, 0x78, 0x0F, 0x09, 0xA9, 0x07, 0xB0, 0x01, 0x20, 0x01, 0x4E, 0x38, 0x32, 0x35, 0x56, 0x20, 0x20, 0x20, 0x00]
let dataToStore = NSData(bytes: integersToStore, length: integersToStore.count)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject(dataToStore, forKey: "mydata")
defaults.synchronize()
// get the data we stored in NSUserDefaults
if let readData = defaults.dataForKey("mydata") {
// determine the number of UInt8 to read from this data
let count = readData.length / sizeof(UInt8)
// create a new UInt8 array with the correct count
var readArray = [UInt8](count: count, repeatedValue: 0)
// copy data into array
readData.getBytes(&readArray, length: count * sizeof(UInt8))
// readArray has what you need
print(readArray)
}
Note: Don't expect the correct result when testing this in a playground.

iOS SDL2 OpenGL ES Cannot Draw Texture

I have been trying to follow the below example but using iOS/Xcode instead of VS2015 (which shows an example of an Android cross-platform project).
Youtube Link
I cannot get the code to display any of my texture at all. No matter what I try I only get a small white rectangle. What am I doing wrong?
This should be OpenGL ES1.x so no shaders should be required.
#import <Foundation/Foundation.h>
#include "SDL.h"
#include <time.h>
#include "SDL_opengles.h"
#define FALSE 0
#define TRUE 1
#ifndef BOOL
#define BOOL int
#endif
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 480
GLuint g_Texture = 0;
BOOL g_Running = TRUE;
SDL_Window *g_SDLWindow = NULL;
SDL_Surface *g_SDLSurface = NULL;
SDL_Renderer *g_SDLRenderer = NULL;
SDL_Texture *g_SDLTexture = NULL;
int g_ScreenHeight = SCREEN_HEIGHT;
int g_ScreenWidth = SCREEN_WIDTH;
unsigned char treeData[420] = {
0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x10, 0x00, 0x10, 0x00, 0x20, 0x08, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01,
0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x83, 0x16, 0x1D, 0x38,
0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x82, 0x16, 0x1D, 0x38, 0xFF, 0x82,
0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x81, 0x16, 0x1D,
0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x84, 0x16, 0x1D, 0x38, 0xFF,
0x83, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x16,
0x1D, 0x38, 0xFF, 0x00, 0x10, 0x50, 0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00,
0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x01, 0x16, 0x1D, 0x38, 0xFF, 0x10,
0x50, 0x6C, 0xFF, 0x81, 0x16, 0x1D, 0x38, 0xFF, 0x85, 0x00, 0x00, 0x00,
0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x83, 0x16, 0x1D, 0x38, 0xFF, 0x85,
0x00, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x00, 0x03, 0x16, 0x1D,
0x38, 0xFF, 0x10, 0x50, 0x6C, 0xFF, 0x16, 0x1D, 0x38, 0xFF, 0x10, 0x50,
0x6C, 0xFF, 0x85, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x00,
0x89, 0x24, 0xBA, 0x24, 0xFF, 0x82, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00,
0x00, 0x00, 0x00, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
0xFF, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x82, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87,
0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF,
0x86, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x24,
0xBA, 0x24, 0xFF, 0x81, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F,
0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF, 0x05, 0x1A, 0x87, 0x2F, 0xFF, 0x24,
0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x1A,
0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF, 0x86, 0x24, 0xBA, 0x24, 0xFF,
0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x87, 0x24, 0xBA, 0x24, 0xFF, 0x81, 0x24,
0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF, 0x24, 0xBA, 0x24, 0xFF,
0x1A, 0x87, 0x2F, 0xFF, 0x8A, 0x24, 0xBA, 0x24, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x88, 0x24, 0xBA, 0x24, 0xFF, 0x02, 0x1A, 0x87, 0x2F, 0xFF,
0x24, 0xBA, 0x24, 0xFF, 0x1A, 0x87, 0x2F, 0xFF, 0x81, 0x24, 0xBA, 0x24,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x84,
0x24, 0xBA, 0x24, 0xFF, 0x00, 0x1A, 0x87, 0x2F, 0xFF, 0x85, 0x24, 0xBA,
0x24, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00,
0x87, 0x24, 0xBA, 0x24, 0xFF, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x52, 0x55, 0x45, 0x56, 0x49,
0x53, 0x49, 0x4F, 0x4E, 0x2D, 0x58, 0x46, 0x49, 0x4C, 0x45, 0x2E, 0x00
};
void LoadTree( void )
{
glGenTextures( 1, &g_Texture );
glBindTexture( GL_TEXTURE_2D, g_Texture );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, treeData+18 );
}
//--------------------------------------------------------------------------------------------
// InitSDL()
//--------------------------------------------------------------------------------------------
void InitSDL( void )
{
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
exit( -1 );
atexit( SDL_Quit );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); // *new*
SDL_DisplayMode currentDisplay;
SDL_GetCurrentDisplayMode( 0, &currentDisplay );
g_ScreenWidth = max( currentDisplay.w, currentDisplay.h );
g_ScreenHeight = min( currentDisplay.w, currentDisplay.h );
SDL_DisplayMode displayMode;
SDL_GetDesktopDisplayMode( 0, &displayMode );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
// PDS: GLES 2 will require shaders etc..
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 1 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 );
g_SDLWindow = SDL_CreateWindow( "Test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
g_ScreenWidth,
g_ScreenHeight,
/* SDL_WINDOW_FULLSCFREEN | */ SDL_WINDOW_OPENGL );
if( g_SDLWindow == NULL )
exit( -1 );
SDL_GL_CreateContext( g_SDLWindow );
glViewport( 0, 0, g_ScreenWidth, g_ScreenHeight ); // Reset The Current Viewport
glMatrixMode( GL_PROJECTION ); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
glRotatef( -90, 0, 0, 1 );
glOrthof( 0.0f, g_ScreenWidth, g_ScreenHeight, 0.0f, -1.0f, 1.0f );
glMatrixMode( GL_MODELVIEW ); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glTranslatef(0.5, 0.5, 0);
glClearColor( 0.9f, 0.9f, 0.9f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
LoadTree();
glShadeModel(GL_SMOOTH);
}
float sq[] =
{
-7, 7, 0,
7, 7, 0,
-7, -7, 0,
7, -7, 0
};
float tri[] =
{
sq[ 0 ], sq[ 1 ], sq[ 2 ],
sq[ 3 ], sq[ 4 ], sq[ 5 ],
sq[ 6 ], sq[ 7 ], sq[ 8 ],
sq[ 6 ], sq[ 7 ], sq[ 8 ],
sq[ 3 ], sq[ 4 ], sq[ 5 ],
sq[ 9 ], sq[ 10], sq[ 11]
};
float texCoords[]=
{
0, 1,
1, 1,
0, 0,
0, 0,
1, 1,
1, 0
};
//--------------------------------------------------------------------------------------------
// Draw()
//--------------------------------------------------------------------------------------------
void Draw( int x, int y )
{
glEnable( GL_TEXTURE_2D );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glBindTexture( GL_TEXTURE_2D, g_Texture );
glPushMatrix();
glDisable( GL_BLEND );
glDisable( GL_CULL_FACE );
glEnable( GL_TEXTURE_2D );
GLfloat tX = (GLfloat) 10.0f;
GLfloat tY = (GLfloat) 10.0f;
GLfloat xOffset = 0;
GLfloat yOffset = 0;
// PDS: Offset the drawing by half character width since all placement will be done from quad centre..
xOffset = tX;
yOffset = tY;
glTranslatef( xOffset + x, yOffset + y, 0.0f);
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glFrontFace( GL_CW );
glVertexPointer( 3, GL_FLOAT, 0, tri );
glTexCoordPointer( 2, GL_FLOAT, 0, texCoords );
glDrawArrays( GL_TRIANGLES, 0, 6 );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
glPopMatrix();
glBindTexture( GL_TEXTURE_2D, 0 );
glEnable( GL_BLEND );
}
//--------------------------------------------------------------------------------------------
// main()
//--------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
InitSDL();
SDL_Event event;
while( g_Running )
{
while( SDL_PollEvent( &event ) )
{
switch( event.type )
{
case SDL_QUIT:
g_Running = false;
break;
}
}
Draw( 100, 100 );
SDL_GL_SwapWindow( g_SDLWindow );
}
SDL_Quit();
return EXIT_SUCCESS;
}
I figured this out.. The ordering of setting the Projection and ModelView uniforms was wrong - it had to be done after the shader program was in use.. and I had some crazy vertice values for the triangles making up the destination rectangle.
The raw TGA loading didn't work very well either so I went back to my original code for loading TGA files.
The below link contains a working example.
Working Example

convert c char to swift

I am trying to conver the following code to swift:
static unsigned char rsa2048Asn1Header[] = {
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00
};
static unsigned char rsa4096Asn1Header[] = {
0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00
};
static unsigned char ecDsaSecp256r1Asn1Header[] = {
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00
};
static unsigned char *asn1HeaderBytes[3] = { rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header };
static unsigned int asn1HeaderSizes[3] = { sizeof(rsa2048Asn1Header), sizeof(rsa4096Asn1Header), sizeof(ecDsaSecp256r1Asn1Header) };
My swift code looks like this:
let rsa2048Asn1Header:[CUnsignedChar] = [0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00]
let rsa4096Asn1Header:[CUnsignedChar] = [0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00]
let ecDsaSecp256r1Asn1Header:[CUnsignedChar] = [0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00]
let asn1HeaderBytes:[[CUnsignedChar]] = [rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header]
let asn1HeaderSizes:[UInt] = [sizeof(rsa2048Asn1Header.dynamicType).toUInt, sizeof(rsa4096Asn1Header.dynamicType).toUInt, sizeof(ecDsaSecp256r1Asn1Header.dynamicType).toUInt]
However i failing at his badly, per example using rsa2048Asn1Header and converting it to NSData:
let data:NSData = NSData(bytes: rsa2048Asn1Header, length:strideofValue(rsa2048Asn1Header))
swift prints with length 8:
<30820122 300d0609>
objc for the following code:
[NSData dataWithBytes:rsa2048Asn1Header length:sizeof(rsa2048Asn1Header)];
prints
<30820122 300d0609 2a864886 f70d0101 01050003 82010f00> size: 24
looking at apple documentation, strideOfvalue should return the right size for each one of those [CUnsignedChar] but that doesnt seem to be the case, my question is shouldnt a [CUnsignedChar] have same size as usigned char [] in objc, if not what could i use to change?
also [[CUnsignedChar]] makes no sense whatsoever in my head, how would the code below convert to swift, should i convert those arrays to an NSString and extract the CString when required, if so what encoding should I use?
static unsigned char *asn1HeaderBytes[3] = { rsa2048Asn1Header, rsa4096Asn1Header, ecDsaSecp256r1Asn1Header };
I don't think strideofValue is the function you are looking for. I haven't heard of it before, but the documentation states:
Returns the least possible interval between distinct instances of T in memory. The result is always positive.
If this is returning 8, that means that the minimum distance between [CUnsignedChar]s in memory is 8 bytes.
To use NSData(data:length:) properly, the second parameter needs to be the size of the array. You can use the count property for this:
let data: NSData = NSData(bytes: rsa2048Asn1Header, length:rsa2048Asn1Header.count)
[[CUnsignedChar]] is an array of arrays (two-dimensional array) of CUnsignedChar.
Your headers are raw bytes, so technically no encoding is 'correct' to convert to NSString. The cryptographic headers you have don't appear to be strings, and contain unprintable characters.
You should not use strideofValue function. 'strideofValue' it's not a replacement for 'sizeof'. Just go for ".count" property.

Does anyone know what's wrong with this Delphi CRC16 algorithm?

This is an exported function in a CRC.dll used by our company's main application. I need to replicate it's incorrect calculation of checksums in our new application written in C#, in order to maintain backward compatibility.
It's all way above my head, but I know there are quite a few very intelligent people on Stackoverflow so I thought I'd try my luck. What's wrong with it? How can I replicate it in C#?
CRC_16_TABLE_1 : array[0..255] of Byte =
(
$00, $80, $80, $00, $80, $00, $00, $80, $80, $00, $00, $80, $00, $80, $80, $00,
$80, $00, $00, $80, $00, $80, $80, $00, $00, $80, $80, $00, $80, $00, $00, $80,
$80, $00, $00, $80, $00, $80, $80, $00, $00, $80, $80, $00, $80, $00, $00, $80,
$00, $80, $80, $00, $80, $00, $00, $80, $80, $00, $00, $80, $00, $80, $80, $00,
$81, $01, $01, $81, $01, $81, $81, $01, $01, $81, $81, $01, $81, $01, $01, $81,
$01, $81, $81, $01, $81, $01, $01, $81, $81, $01, $01, $81, $01, $81, $81, $01,
$01, $81, $81, $01, $81, $01, $01, $81, $81, $01, $01, $81, $01, $81, $81, $01,
$81, $01, $01, $81, $01, $81, $81, $01, $01, $81, $81, $01, $81, $01, $01, $81,
$83, $03, $03, $83, $03, $83, $83, $03, $03, $83, $83, $03, $83, $03, $03, $83,
$03, $83, $83, $03, $83, $03, $03, $83, $83, $03, $03, $83, $03, $83, $83, $03,
$03, $83, $83, $03, $83, $03, $03, $83, $83, $03, $03, $83, $03, $83, $83, $03,
$83, $03, $03, $83, $03, $83, $83, $03, $03, $83, $83, $03, $83, $03, $03, $83,
$02, $82, $82, $02, $82, $02, $02, $82, $82, $02, $02, $82, $02, $82, $82, $02,
$82, $02, $02, $82, $02, $82, $82, $02, $02, $82, $82, $02, $82, $02, $02, $82,
$82, $02, $02, $82, $02, $82, $82, $02, $02, $82, $82, $02, $82, $02, $02, $82,
$02, $82, $82, $02, $82, $02, $02, $82, $82, $02, $02, $82, $02, $82, $82, $02
);
CRC_16_TABLE_2 : array[0..255] of Byte =
(
$00, $05, $0f, $0a, $1b, $1e, $14, $11, $33, $36, $3c, $39, $28, $2d, $27, $22,
$63, $66, $6c, $69, $78, $7d, $77, $72, $50, $55, $5f, $5a, $4b, $4e, $44, $41,
$c3, $c6, $cc, $c9, $d8, $dd, $d7, $d2, $f0, $f5, $ff, $fa, $eb, $ee, $e4, $e1,
$a0, $a5, $af, $aa, $bb, $be, $b4, $b1, $93, $96, $9c, $99, $88, $8d, $87, $82,
$83, $86, $8c, $89, $98, $9d, $97, $92, $b0, $b5, $bf, $ba, $ab, $ae, $a4, $a1,
$e0, $e5, $ef, $ea, $fb, $fe, $f4, $f1, $d3, $d6, $dc, $d9, $c8, $cd, $c7, $c2,
$40, $45, $4f, $4a, $5b, $5e, $54, $51, $73, $76, $7c, $79, $68, $6d, $67, $62,
$23, $26, $2c, $29, $38, $3d, $37, $32, $10, $15, $1f, $1a, $0b, $0e, $04, $01,
$03, $06, $0c, $09, $18, $1d, $17, $12, $30, $35, $3f, $3a, $2b, $2e, $24, $21,
$60, $65, $6f, $6a, $7b, $7e, $74, $71, $53, $56, $5c, $59, $48, $4d, $47, $42,
$c0, $c5, $cf, $ca, $db, $de, $d4, $d1, $f3, $f6, $fc, $f9, $e8, $ed, $e7, $e2,
$a3, $a6, $ac, $a9, $b8, $bd, $b7, $b2, $90, $95, $9f, $9a, $8b, $8e, $84, $81,
$80, $85, $8f, $8a, $9b, $9e, $94, $91, $b3, $b6, $bc, $b9, $a8, $ad, $a7, $a2,
$e3, $e6, $ec, $e9, $f8, $fd, $f7, $f2, $d0, $d5, $df, $da, $cb, $ce, $c4, $c1,
$43, $46, $4c, $49, $58, $5d, $57, $52, $70, $75, $7f, $7a, $6b, $6e, $64, $61,
$20, $25, $2f, $2a, $3b, $3e, $34, $31, $13, $16, $1c, $19, $08, $0d, $07, $02
);
function CRC_16( var buf : array of Byte; Length : Word; Flag : Byte )
: Word; export;
var
i : Word;
a1, a2, a3 : Byte;
begin
a1 := 0;
a2 := 0;
if (Flag = CRC_MAKE) then
begin
buf[Length-2] := 0;
buf[Length-1] := 0;
end;
for i := 0 to Length-1 do
begin
a3 := a1;
a1 := CRC_16_TABLE_1[a3] xor a2;
a2 := CRC_16_TABLE_2[a3] xor Buf[i];
end;
if (Flag = CRC_MAKE) then
begin
buf[Length-2] := a1;
buf[Length-1] := a2;
end;
result := a1 * 256 + a2;
end;
Here is a C# version of your Delphi code:
static int[] CRC_16_TABLE_1 = {
0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80,
0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80,
0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x00,
0x81, 0x01, 0x01, 0x81, 0x01, 0x81, 0x81, 0x01, 0x01, 0x81, 0x81, 0x01, 0x81, 0x01, 0x01, 0x81,
0x01, 0x81, 0x81, 0x01, 0x81, 0x01, 0x01, 0x81, 0x81, 0x01, 0x01, 0x81, 0x01, 0x81, 0x81, 0x01,
0x01, 0x81, 0x81, 0x01, 0x81, 0x01, 0x01, 0x81, 0x81, 0x01, 0x01, 0x81, 0x01, 0x81, 0x81, 0x01,
0x81, 0x01, 0x01, 0x81, 0x01, 0x81, 0x81, 0x01, 0x01, 0x81, 0x81, 0x01, 0x81, 0x01, 0x01, 0x81,
0x83, 0x03, 0x03, 0x83, 0x03, 0x83, 0x83, 0x03, 0x03, 0x83, 0x83, 0x03, 0x83, 0x03, 0x03, 0x83,
0x03, 0x83, 0x83, 0x03, 0x83, 0x03, 0x03, 0x83, 0x83, 0x03, 0x03, 0x83, 0x03, 0x83, 0x83, 0x03,
0x03, 0x83, 0x83, 0x03, 0x83, 0x03, 0x03, 0x83, 0x83, 0x03, 0x03, 0x83, 0x03, 0x83, 0x83, 0x03,
0x83, 0x03, 0x03, 0x83, 0x03, 0x83, 0x83, 0x03, 0x03, 0x83, 0x83, 0x03, 0x83, 0x03, 0x03, 0x83,
0x02, 0x82, 0x82, 0x02, 0x82, 0x02, 0x02, 0x82, 0x82, 0x02, 0x02, 0x82, 0x02, 0x82, 0x82, 0x02,
0x82, 0x02, 0x02, 0x82, 0x02, 0x82, 0x82, 0x02, 0x02, 0x82, 0x82, 0x02, 0x82, 0x02, 0x02, 0x82,
0x82, 0x02, 0x02, 0x82, 0x02, 0x82, 0x82, 0x02, 0x02, 0x82, 0x82, 0x02, 0x82, 0x02, 0x02, 0x82,
0x02, 0x82, 0x82, 0x02, 0x82, 0x02, 0x02, 0x82, 0x82, 0x02, 0x02, 0x82, 0x02, 0x82, 0x82, 0x02
};
static int[] CRC_16_TABLE_2 = {
0x00, 0x05, 0x0f, 0x0a, 0x1b, 0x1e, 0x14, 0x11, 0x33, 0x36, 0x3c, 0x39, 0x28, 0x2d, 0x27, 0x22,
0x63, 0x66, 0x6c, 0x69, 0x78, 0x7d, 0x77, 0x72, 0x50, 0x55, 0x5f, 0x5a, 0x4b, 0x4e, 0x44, 0x41,
0xc3, 0xc6, 0xcc, 0xc9, 0xd8, 0xdd, 0xd7, 0xd2, 0xf0, 0xf5, 0xff, 0xfa, 0xeb, 0xee, 0xe4, 0xe1,
0xa0, 0xa5, 0xaf, 0xaa, 0xbb, 0xbe, 0xb4, 0xb1, 0x93, 0x96, 0x9c, 0x99, 0x88, 0x8d, 0x87, 0x82,
0x83, 0x86, 0x8c, 0x89, 0x98, 0x9d, 0x97, 0x92, 0xb0, 0xb5, 0xbf, 0xba, 0xab, 0xae, 0xa4, 0xa1,
0xe0, 0xe5, 0xef, 0xea, 0xfb, 0xfe, 0xf4, 0xf1, 0xd3, 0xd6, 0xdc, 0xd9, 0xc8, 0xcd, 0xc7, 0xc2,
0x40, 0x45, 0x4f, 0x4a, 0x5b, 0x5e, 0x54, 0x51, 0x73, 0x76, 0x7c, 0x79, 0x68, 0x6d, 0x67, 0x62,
0x23, 0x26, 0x2c, 0x29, 0x38, 0x3d, 0x37, 0x32, 0x10, 0x15, 0x1f, 0x1a, 0x0b, 0x0e, 0x04, 0x01,
0x03, 0x06, 0x0c, 0x09, 0x18, 0x1d, 0x17, 0x12, 0x30, 0x35, 0x3f, 0x3a, 0x2b, 0x2e, 0x24, 0x21,
0x60, 0x65, 0x6f, 0x6a, 0x7b, 0x7e, 0x74, 0x71, 0x53, 0x56, 0x5c, 0x59, 0x48, 0x4d, 0x47, 0x42,
0xc0, 0xc5, 0xcf, 0xca, 0xdb, 0xde, 0xd4, 0xd1, 0xf3, 0xf6, 0xfc, 0xf9, 0xe8, 0xed, 0xe7, 0xe2,
0xa3, 0xa6, 0xac, 0xa9, 0xb8, 0xbd, 0xb7, 0xb2, 0x90, 0x95, 0x9f, 0x9a, 0x8b, 0x8e, 0x84, 0x81,
0x80, 0x85, 0x8f, 0x8a, 0x9b, 0x9e, 0x94, 0x91, 0xb3, 0xb6, 0xbc, 0xb9, 0xa8, 0xad, 0xa7, 0xa2,
0xe3, 0xe6, 0xec, 0xe9, 0xf8, 0xfd, 0xf7, 0xf2, 0xd0, 0xd5, 0xdf, 0xda, 0xcb, 0xce, 0xc4, 0xc1,
0x43, 0x46, 0x4c, 0x49, 0x58, 0x5d, 0x57, 0x52, 0x70, 0x75, 0x7f, 0x7a, 0x6b, 0x6e, 0x64, 0x61,
0x20, 0x25, 0x2f, 0x2a, 0x3b, 0x3e, 0x34, 0x31, 0x13, 0x16, 0x1c, 0x19, 0x08, 0x0d, 0x07, 0x02
};
static int CRC_16(byte[] buf, int length, bool make)
{
int a1 = 0;
int a2 = 0;
if (make)
{
buf[length-2] = 0;
buf[length-1] = 0;
}
for (int i=0; i<length; i++)
{
int a3 = a1;
a1 = (CRC_16_TABLE_1[a3] ^ a2) & 0xff;
a2 = (CRC_16_TABLE_2[a3] ^ buf[i]) & 0xff;
}
if (make)
{
buf[length-2] = (byte)a1;
buf[length-1] = (byte)a2;
}
return a1*256+a2;
}
I've used int throughout to reduce the amount of casting that needs to be done.
As for your Delphi code, I fell foul of the fact that your length parameter is a mere 16-bit integer. My test file was >32kb in size and so that confused me for a while. I'd also comment that unsigned types are inappropriate for loop variables. Your variable i being typed as a Word will result in AVs if ever you call the function with a length of 0. Of course, the accesses of buf[Length-1] and buf[Length-2] are also a problem when the length is too small.
Well, I can't rewrite the thing for you, but its general arrangement is pretty darned obvious... Pascal's not that different from any other language!
Try this: go out to the Internet and find a CRC-16 algorithm already written in C# that works. Then, put the code of the two routines side-by-side. You're looking for a routine that also has two fixed tables of constants, that also loops through them as this routine does, but that's written in C#. Then, gosh... the necessary adjustments ought to be pretty obvious at that point, don't you think?? (I mean, the entire guts of the thing are, like, 25 lines long?) :-}

Resources