memory leak in utf8 string parser - c

typedef struct _utf8_multibyte {
uint8_t bytes[4]; /* always max of 4 */
int used; /* how many of the 4 bytes are used */
} utf8_multibyte_t;
typedef struct _utf8_string {
uint8_t *raw; /* raw string buffer */
uint32_t *chars; /* codepoints comprising the string */
uint64_t length; /* number of codepoints in string */
} utf8_string_t;
...
utf8_string_t *utf8_init(unsigned char *s) {
utf8_string_t *str = (utf8_string_t*)malloc(sizeof(utf8_string_t*));
if (!str) {
perror("utf8_string_t init");
return NULL;
}
str->raw = (uint8_t*)malloc(strlen(s) * sizeof(uint8_t));
if (!str->raw) {
perror("malloc raw");
return NULL;
}
memcpy(str->raw, s, strlen(s));
str->length = utf8_strlen(s);
str->chars = (uint32_t*)malloc(str->length * sizeof(uint32_t));
if (!str->chars) {
perror("malloc chars");
return NULL;
}
uint8_t *p = s;
utf8_multibyte_t mb;
mb_clear(&mb);
int j = 0;
while (*p != '\0') {
int len = utf8len(*p);
mb.used = len;
mb.bytes[0] = *p++;
for (int i = 1; i < len; ++i) mb.bytes[i] = *p++;
uint32_t cp = utf8_decode(&mb);
str->chars[j++] = cp;
printf("%x ", str->chars[j - 1]);
mb_clear(&mb);
}
return str;
}
I am testing if the initialization is going correctly with this code:
unsigned char data[] = {
0xe5, 0xbd, 0xbc, 0xe5, 0xa5, 0xb3, 0xe3, 0x81, 0xaf, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa4, 0xe3,
0x82, 0xb9, 0xe3, 0x82, 0x92, 0xe9, 0xa3, 0x9f, 0xe3, 0x81, 0xb9, 0xe3, 0x81, 0x9f, 0xe3, 0x81,
0x8b, 0xe3, 0x81, 0xa3, 0xe3, 0x81, 0x9f, 0xe3, 0x81, 0x8b, 0xe3, 0x82, 0x89, 0xe8, 0xb2, 0xb7,
0xe3, 0x81, 0x84, 0xe3, 0x81, 0xab, 0xe5, 0x87, 0xba, 0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x91, 0xe3,
0x81, 0xbe, 0xe3, 0x81, 0x97, 0xe3, 0x81, 0x9f, 0xe3, 0x80, 0x82, 0x0
};
unsigned char data1[] = {
0xe5, 0xbd, 0xbc, 0xe5, 0xa5, 0xb3, 0xe3, 0x81, 0xaf, 0xe3, 0x82, 0xa2, 0xe3, 0x82, 0xa4, 0xe3,
0x82, 0xb9, 0xe3, 0x82, 0x92, 0xe9, 0xa3, 0x9f, 0xe3, 0x81, 0xb9, 0xe3, 0x81, 0x9f, 0xe3, 0x81,
0x8b, 0xe3, 0x81, 0xa3, 0xe3, 0x81, 0x9f, 0xe3, 0x81, 0x8b, 0xe3, 0x82, 0x89, 0xe8, 0xb2, 0xb7,
0xe3, 0x81, 0x84, 0xe3, 0x81, 0xab, 0xe5, 0x87, 0xba, 0xe3, 0x81, 0x8b, 0xe3, 0x81, 0x91, 0xe3,
0x81, 0xbe, 0xe3, 0x81, 0x97, 0xe3, 0x81, 0x9f, 0xe3, 0x80, 0x82, 0x0
};
utf8_string_t *str1 = utf8_init(data);
utf8_string_t *str2 = utf8_init(data1);
printf("%d %d\n", str1->length, str2->length);
/*utf8_free(str1);
utf8_free(str2);*/
One of the strings sometimes doesn't get initialized and when it does it reports it's length as 0 when it should be 25. I tried printing out the codepoints from the strings as they're initialized and they're completely ok so I am led to believe it's got something to do with the raw string allocation but I am not sure.
I know this has something to do with my memory management but I have been staring at this code for 2 days and still cannot figure out where my mistake is. Please help me.
EDIT:
I think I managed to fix it thanks to the recommendations in the comments. Here's the updated code:
utf8_string_t *utf8_init(const uint8_t *s) {
utf8_string_t *str = malloc(sizeof(utf8_string_t));
if (!str) {
free(str);
return NULL;
}
uint64_t rawlen = strlen_uchar(s);
str->raw = malloc((rawlen + 1) * sizeof(uint8_t));
if (!str->raw) {
free(str->raw);
free(str);
return NULL;
}
memcpy(str->raw, s, rawlen + 1);
str->length = utf8_strlen(s);
str->chars = malloc(str->length * sizeof(uint32_t));
if (!str->chars) {
free(str->raw);
free(str->chars);
free(str);
return NULL;
}
uint8_t *p = (uint8_t*)s;
utf8_multibyte_t mb;
mb_clear(&mb);
int j = 0;
while (*p != '\0') {
int len = utf8len(*p);
mb.used = len;
mb.bytes[0] = *p++;
for (int i = 1; i < len; ++i) mb.bytes[i] = *p++;
uint32_t cp = utf8_decode(&mb);
str->chars[j++] = cp;
mb_clear(&mb);
}
return str;
}
Please do tell if there are still parts of it which might bring about undefined behavior/bugs.

Related

aes 128 encryption and decryption in c without any seperate libraries and header files needed mainly in diagnostics point of view

#include <stdio.h>
#include <stdint.h>
#define Nb 4
#define Nk 4
#define Nr 10
uint8_t state[4 * Nb];
uint8_t w[Nb * (Nr + 1) * 4];
#define mul2(x) ((x << 1) ^ (((x >> 7) & 1) * 0x1b))
#define mul3(x) (mul2(x) ^ x)
#define mul9(x) (mul2(mul2(mul2(x))) ^ x)
#define mul11(x) (mul2(mul2(mul2(x)) ^ x) ^ x)
#define mul13(x) (mul2(mul2(mul2(x) ^ x)) ^ x)
#define mul14(x) (mul2(mul2(mul2(x) ^ x) ^ x))
i dont want to use lookup table for xor multiplications so used this above method as reference to caliculate the values runtime
uint8_t sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};
uint8_t inv_sbox[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
uint8_t rcon[256] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d
};
uint32_t sub_bytes_word(uint32_t word) {
uint8_t* bytes = (uint8_t*)&word;
for (int i = 0; i < 4; i++) {
bytes[i] = sbox[bytes[i]];
}
return word;
}
uint32_t inv_sub_bytes_word(uint32_t word) {
uint8_t* bytes = (uint8_t*)&word;
for (int i = 0; i < 4; i++) {
bytes[i] = inv_sbox[bytes[i]];
}
return word;
}
uint32_t rot_word(uint32_t word) {
return (word << 8) | (word >> 24);
}
uint32_t sub_word(uint32_t word) {
return sub_bytes_word(word);
}
uint32_t inv_word(uint32_t word) {
return inv_sub_bytes_word(word);
}
void key_expansion(uint8_t* key) {
for (int i = 0; i < Nk; i++) {
w[i] = key[4 * i] << 24 | key[4 * i + 1] << 16 | key[4 * i + 2] << 8 | key[4 * i + 3];
}
for (int i = Nk; i < 4 * (Nr + 1); i++) {
uint32_t temp = w[i - 1];
if (i % Nk == 0) {
temp = sub_word(rot_word(temp)) ^ rcon[i / Nk - 1];
} else if (Nk > 6 && i % Nk == 4) {
temp = sub_word(temp);
}
w[i] = w[i - Nk] ^ temp;
}
for (int i = 0; i < 4 * (Nr + 1); i++) {
w[i] = inv_word(w[i]);
}
}
void sub_bytes() {
for (int i = 0; i < 4 * Nb; i++) {
state[i] = sbox[state[i]];
}
}
void shift_rows() {
uint8_t temp[4 * Nb];
for (int i = 0; i < 4 * Nb; i++) {
temp[i] = state[i];
}
for (int i = 0; i < Nb; i++) {
state[i] = temp[i];
state[i + 4] = temp[i + 4];
state[i + 8] = temp[i + 8];
state[i + 12] = temp[i + 12];
}
state[1] = temp[5];
state[5] = temp[9];
state[9] = temp[13];
state[13] = temp[1];
state[2] = temp[10];
state[6] = temp[14];
state[10] = temp[2];
state[14] = temp[6];
state[3] = temp[15];
state[7] = temp[3];
state[11] = temp[7];
state[15] = temp[11];
}
void mix_columns() {
uint8_t temp[4 * Nb];
for (int i = 0; i < 4 * Nb; i++) {
temp[i] = state[i];
}
for (int i = 0; i < Nb; i++) {
state[0 + 4 * i] = mul2(temp[0 + 4 * i]) ^ mul3(temp[1 + 4 * i]) ^ temp[2 + 4 * i] ^ temp[3 + 4 * i];
state[1 + 4 * i] = temp[0 + 4 * i] ^ mul2(temp[1 + 4 * i]) ^ mul3(temp[2 + 4 * i]) ^ temp[3 + 4 * i];
state[2 + 4 * i] = temp[0 + 4 * i] ^ temp[1 + 4 * i] ^ mul2(temp[2 + 4 * i]) ^ mul3(temp[3 + 4 * i]);
state[3 + 4 * i] = mul3(temp[0 + 4 * i]) ^ temp[1 + 4 * i] ^ temp[2 + 4 * i] ^ mul2(temp[3 + 4 * i]);
}
}
void add_round_key(int round) {
for (int i = 0; i < 4 * Nb; i++) {
state[i] ^= w[round * 4 * Nb + i];
}
}
void aes_round(int round) {
sub_bytes();
shift_rows();
mix_columns();
add_round_key(round);
}
void inv_sub_bytes() {
for (int i = 0; i < 4 * Nb; i++) {
state[i] = inv_sbox[state[i]];
}
}
void inv_shift_rows() {
uint8_t temp[4 * Nb];
for (int i = 0; i < 4 * Nb; i++) {
temp[i] = state[i];
}
for (int i = 0; i < Nb; i++) {
state[i] = temp[i];
state[i + 4] = temp[i + 4];
state[i + 8] = temp[i + 8];
state[i + 12] = temp[i + 12];
}
state[1] = temp[13];
state[5] = temp[1];
state[9] = temp[5];
state[13] = temp[9];
state[2] = temp[10];
state[6] = temp[14];
state[10] = temp[2];
state[14] = temp[6];
state[3] = temp[7];
state[7] = temp[11];
state[11] = temp[15];
state[15] = temp[3];
}
void inv_mix_columns() {
uint8_t temp[4 * Nb];
for (int i = 0; i < 4 * Nb; i++) {
temp[i] = state[i];
}
for (int i = 0; i < Nb; i++) {
state[0 + 4 * i] = mul14(temp[0 + 4 * i]) ^ mul11(temp[1 + 4 * i]) ^ mul13(temp[2 + 4 * i]) ^ mul9(temp[3 + 4 * i]);
state[1 + 4 * i] = mul9(temp[0 + 4 * i]) ^ mul14(temp[1 + 4 * i]) ^ mul11(temp[2 + 4 * i]) ^ mul13(temp[3 + 4 * i]);
state[2 + 4 * i] = mul13(temp[0 + 4 * i]) ^ mul9(temp[1 + 4 * i]) ^ mul14(temp[2 + 4 * i]) ^ mul11(temp[3 + 4 * i]);
state[3 + 4 * i] = mul11(temp[0 + 4 * i]) ^ mul13(temp[1 + 4 * i]) ^ mul9(temp[2 + 4 * i]) ^ mul14(temp[3 + 4 * i]);
}
}
void inv_aes_round(int round) {
add_round_key(round);
inv_mix_columns();
inv_shift_rows();
inv_sub_bytes();
}
Here i tried encrypt and decrypt the plain text
void encrypt(uint8_t* plaintext, uint8_t* key) {
for (int i = 0; i < 4 * Nb; i++) {
state[i] = plaintext[i];
}
key_expansion(key);
add_round_key(0);
for (int i = 1; i <= Nr; i++) {
aes_round(i);
}
}
void decrypt(uint8_t* ciphertext, uint8_t* key) {
for (int i = 0; i < 4 * Nb; i++) {
state[i] = ciphertext[i];
}
key_expansion(key);
add_round_key(Nr);
for (int i = Nr - 1; i >= 1; i--) {
inv_aes_round(i);
}
inv_aes_round(0);
}
My main function
int main() {
// Set key and plaintext
uint8_t key[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
uint8_t plaintext[16] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
uint8_t ciphertext[16];
uint8_t decrypted[16];
// Plaintext
printf("Original plaintext: ");
for (int i = 0; i < 16; i++) {
printf("%02x ", plaintext[i]);
}
printf("\n");
// Encrypt plaintext
encrypt(plaintext, key);
printf("Ciphertext: ");
for (int i = 0; i < 4 * Nb; i++) {
printf("%02x ", state[i]);
ciphertext[i] = state[i];
}
printf("\n");
// Decrypt ciphertext
decrypt(ciphertext, key);
printf("Decrypted: ");
for (int i = 0; i < 4 * Nb; i++) {
printf("%02x ", state[i]);
decrypted[i] = state[i];
}
printf("\n");
return 0;
}
i have tried improving the code many times by assigning seperate functions to implement but every time my output is wrong .\
This is my output ; whatever i tried iam not able to get correct decrypt . iam not sure where i did mistake .
Original plaintext: 01 23 45 67 89 ab cd ef 01 23 45 67 89 ab cd ef
Ciphertext: ec d5 9c a4 41 cb cb e5 08 02 a3 cc 7c 39 be 74
Decrypted: 37 b8 75 c5 01 5c 74 14 b4 e9 11 d8 3c 16 cd c2

Finding polynomial used in CRC-8 calculation table

Here as most rated answer (Implementing CRC8 on Arduino to write to MLX90614) is a good example of CRC-8 calculation/finding using a lookup table. I would like to know what is the polynomial used to generate those table values.
So given the table, how can I recover the polynomial? I tried using this nice calculator of tables, but cannot get the same values.
static const uint8_t crc_table[] = {
0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31,
0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65,
0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9,
0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd,
0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1,
0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2,
0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe,
0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a,
0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16,
0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42,
0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80,
0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4,
0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8,
0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c,
0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10,
0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34,
0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f,
0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b,
0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7,
0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83,
0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef,
0xfa, 0xfd, 0xf4, 0xf3
};
uint8_t
crc8(uint8_t *p, uint8_t len)
{
uint16_t i;
uint16_t crc = 0x0;
while (len--) {
i = (crc ^ *p++) & 0xFF;
crc = (crc_table[i] ^ (crc << 8)) & 0xFF;
}
return crc & 0xFF;
}
Well, the link you provided shows the exact same table for the (default) polynomial 0x07, which is (x^8) + x^2 + x + 1. So this should already answer your question.
With the above being said, for a general "target" table, you can very easily brute force the needed polynomial.
I'll let the code speak for itself, here's a working example:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
static const uint8_t target[256] = {
// ... fill in the values here ...
};
void compute_table(uint8_t table[256], uint8_t polynomial) {
uint8_t crc = 0x80;
size_t i, j;
memset(table, 0, 256);
for (i = 1; i < 256; i <<= 1) {
if (crc & 0x80)
crc = (crc << 1) ^ polynomial;
else
crc <<= 1;
for (j = 0; j < i; j++)
table[i + j] = crc ^ table[j];
}
}
int main(void) {
uint8_t table[256];
uint8_t poly;
bool found;
size_t i;
for (poly = 1; poly != 0; poly++) {
compute_table(table, poly);
found = true;
for (i = 0; i < 256; i++) {
if (table[i] != target[i]) {
found = false;
break;
}
}
if (found)
printf("Found polynomial: 0x%02x\n", poly);
}
return 0;
}
And indeed, plugging in the table you provide, the above code outputs:
Found polynomial: 0x07
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
unsigned char table[256] = {0};
void crc_table_create(unsigned char *pdata, unsigned char factor)
{
unsigned char temp;
for (int i = 0; i < 256; i++)
{
pdata[i] = i;
}
for (int i = 0; i < 256; i++)
{
for (int j = 7; j >= 0; j--)
{
temp = pdata[i] & 0x80; // take the MSB bit
if (temp) // the MSB bit is 1
{
pdata[i] = pdata[i] << 1;
pdata[i] ^= factor;
}
else
{
pdata[i] = pdata[i] << 1;
}
}
// printf("table[%i]= 0x%02x", i, table[i]);
// getchar();
}
}
int main(void)
{
int i, j = 0;
uint8_t poly = 0x07; // X8 + X2 + X1 + 1 (100000111B the MSB bit is mute, so it turn to 0x07)
crc_table_create(table, poly);
for (i = 0; i < 256; i++)
{
if (i % 12 == 0) {
printf("\n");
}
printf("0x%02x, ", table[i]);
}
printf("\n");
return 1;
}
Here is the CRC8 table generater, after run it, the 'table[256]' is the result, enjoy!

Is there an efficient way to compare these arrays?

I have a NFC scanner that obtains a tag's UID and stores it in byte TagReadB[4].
I then need to compare it to a large number of other byte arrays to see if it matches with them (i.e. if it's a recognised tag).
The recognised tags are stored like this.
uint8_t RED1[4] = {0x15, 0x4C, 0xA9, 0xFB};
uint8_t RED2[4] = {0x67, 0xFC, 0x8A, 0x16};
uint8_t RED3[4] = {0xB7, 0xC4, 0xEA, 0xA4};
uint8_t RED4[4] = {0xE7, 0x32, 0xE7, 0xA4};
uint8_t RED5[4] = {0x87, 0x33, 0xED, 0x74};
uint8_t RED6[4] = {0xB7, 0x56, 0xFA, 0xA4};
uint8_t RED7[4] = {0xB5, 0x8A, 0xB6, 0xFB};
uint8_t RED8[4] = {0x07, 0xA6, 0xF3, 0xA4};
uint8_t RED9[4] = {0xE5, 0xB2, 0x9E, 0xFB};
uint8_t RED10[4] = {0x87, 0xF8, 0x8A, 0x16};
uint8_t RED11[4] = {0x47, 0x93, 0xDA, 0xA4};
uint8_t RED12[4] = {0x87, 0x1D, 0x8A, 0x16};
uint8_t RED13[4] = {0x85, 0x83, 0xB1, 0xFB};
uint8_t RED14[4] = {0x55, 0x33, 0x9C, 0xFB};
uint8_t RED15[4] = {0x45, 0x39, 0xB7, 0xFB};
uint8_t RED16[4] = {0xA5, 0xED, 0xA5, 0xFB};
uint8_t RED17[4] = {0x85, 0x6E, 0xA1, 0xFB};
uint8_t RED18[4] = {0x17, 0xC3, 0xEF, 0xA4};
uint8_t RED19[4] = {0x37, 0xCA, 0xEB, 0xA4};
uint8_t RED20[4] = {0x15, 0x66, 0xA0, 0xFB};
uint8_t YELLOW1[4] = {0x27, 0x44, 0x73, 0xE5};
uint8_t YELLOW2[4] = {0xD7, 0x44, 0xCB, 0xE2};
uint8_t YELLOW3[4] = {0x87, 0x6E, 0x78, 0xE5};
uint8_t YELLOW4[4] = {0x27, 0x49, 0x63, 0xE5};
uint8_t YELLOW5[4] = {0xA7, 0x0D, 0x6C, 0xE5};
uint8_t YELLOW6[4] = {0x87, 0x96, 0x69, 0xE5};
uint8_t YELLOW7[4] = {0x37, 0xF9, 0xCA, 0xE2};
uint8_t YELLOW8[4] = {0xD7, 0xAE, 0xCB, 0xE2};
uint8_t YELLOW9[4] = {0xA7, 0xE3, 0x78, 0xE5};
uint8_t YELLOW10[4] = {0x47, 0x72, 0x90, 0xE5};
uint8_t BLUE1[4] = {0x73, 0xD5, 0xB7, 0xAC};
uint8_t BLUE2[4] = {0x1D, 0x5D, 0xFC, 0x69};
uint8_t BLUE3[4] = {0xBD, 0xEC, 0x8F, 0x12};
uint8_t BLUE4[4] = {0xE6, 0x9F, 0x54, 0x73};
uint8_t BLUE5[4] = {0x38, 0x74, 0x7E, 0x33};
uint8_t BLUE6[4] = {0x6D, 0x05, 0x3E, 0x12};
uint8_t BLUE7[4] = {0x9C, 0x6B, 0x4A, 0x73};
I can do the following but there must be an easier way without having to repeat 20 OR statements?
if (!memcmp(TagReadB, RED1, 4) || !memcmp(TagReadB, RED2, 4) || ...) {
//do something
}
Even better, it would be great to test on what colour of the recognised tag it matches with because there will be the same action for each colour.
e.g. if it's a red tag do x, yellow tag do y, blue tag do z.
Many thanks.
You can expand your data to
struct {uint8_t tag[4], uint8_t type}
data[] = {
{ {0x15, 0x4C, 0xA9, 0xFB}, RED},
// ...
{ {0xD7, 0xAE, 0xCB, 0xE2}, YELLOW },
// ...
};
with
#define RED 1
// etc.
(or a const byte or an enum)
Then loop this list until a match and return the resulting data[i].type
or return a 0 for "not found"
You could store the tags in multidimensional arrays:
uint8_t RED_TAGS[][4] = {
{0x15, 0x4C, 0xA9, 0xFB},
{0x67, 0xFC, 0x8A, 0x16},
...
};
uint8_t YELLOW_TAGS[][4] = {
{0x15, 0x4C, 0xA9, 0xFB},
{0x67, 0xFC, 0x8A, 0x16},
...
};
uint8_t BLUE_TAGS[][4] = {
{0x15, 0x4C, 0xA9, 0xFB},
{0x67, 0xFC, 0x8A, 0x16},
...
}
Now you can check if a tag is in one of the multidimensional arrays using a for loop:
int is_tag_in_array(uint8_t array[][4], int size, uint8_t tag[4]) {
for (int i=0;i<size;i++) {
if (memcmp(array[i], tag, 4) == 0)
return 1;
}
return 0;
}
This way you can check for the color like this:
if (is_tag_in_array(RED_TAGS, 20, TagReadB)) {
// Do something for a red tag
} else if (is_tag_in_array(YELLOW_TAGS, 10, TagReadB)) {
// Do something for a yellow tag
} else if (is_tag_in_array(BLUE_TAGS, 7, TagReadB) {
// Do something for a blue tag
} else {
// Didn't match any color
}

Encryption Implementation - Confusing results

I'm trying to use simple encryption/decryption (treyfer) for a project of mine, but there's no reference implementation of decryption available. What I've got (based off of the Wikipedia implementation) is:
uint8_t rotl(uint8_t x) {
return (x << 1) | (x >> 7);
}
uint8_t rotr(uint8_t x) {
return (x >> 1) | (x << 7);
}
void encrypt (uint8_t text[8], uint8_t key[8]) {
int r, i;
uint8_t t;
for (r=0; r<NUMROUNDS; r++) {
text[8] = text[0];
for (i=0; i<8; i++) {
text[i+1] = rotl((text[i+1] + sbox[(key[i] + text[i]) % 256]));
}
text[0] = text[8];
}
}
void decrypt (uint8_t text[8], uint8_t key[8]) {
int r, i;
uint8_t t;
for (r=0; r<NUMROUNDS; r++) {
text[8] = text[0];
for (i=8; i>=0; --i) {
text[i+1] = rotr(text[i+1]) - sbox[(key[i] + text[i]) % 256];
}
text[0] = text[8];
}
}
void printhex(uint8_t text[8]) {
for(int i = 0; i < 8; i++) {
printf("%02x", text[i]);
}
}
int main() {
char text[8+1] = "AAAAAAAA";
char key[8+1] = "AAAAAAAA";
puts("plaintext:");
printhex(text);
puts("\nkey:");
printhex(key);
puts("\nencrypted:");
encrypt(text, key);
printhex(text);
puts("\ndecrypted:");
decrypt(text, key);
printhex(text);
}
Where Sbox is the AES S-box, and NUMROUNDS = 128
However, when I run this, I get wildly different results for the plaintext and the decrypted value, suggesting either my encryption or decryption is incorrect, but I can't quite see how. Hoping I haven't missed anything too painful.
The output I get is:
plaintext:
4141414141414141
key:
4141414141414141
encrypted:
658ed27d394127a0
decrypted:
a0460a65d755953f
I assume your implementation is based on this: https://en.wikipedia.org/wiki/Treyfer
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define NUMROUNDS 100
static const uint8_t sbox[256] = {
//0 1 2 3 4 5 6 7 8 9 A B C D E F
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 };
void treyfer_encrypt(uint8_t text[8], uint8_t const key[8])
{
unsigned i;
uint8_t t = text[0];
for (i = 0; i < 8*NUMROUNDS; i++) {
t += key[i%8];
t = sbox[t] + text[(i+1)%8];
text[(i+1) % 8] = t = (t << 1) | (t >> 7); /* Rotate left 1 bit */
}
}
void encrypt(uint8_t text[8], uint8_t const key[8])
{
unsigned int i = 0;
unsigned int j = 0;
uint8_t t = 0;
t = text[0];
for (j = 0; j < NUMROUNDS; j++)
{
for (i = 0; i < 8; i++)
{
t = t + key[i];
t = sbox[t] + text[(i + 1) % 8];
t = (t << 1) | (t >> 7);
text[(i + 1) % 8] = t;
}
}
}
void decrypt(uint8_t text[8], uint8_t const key[8])
{
int i = 0;
int j = 0;
uint8_t top = 0;
uint8_t bottom = 0;
for (j = 0; j < NUMROUNDS; j++)
{
for (i = 7; i >= 0; i--)
{
top = text[i] + key[i];
top = sbox[top];
bottom = text[(i + 1) % 8];
bottom = (bottom >> 1) | (bottom << 7);
text[(i + 1) % 8] = bottom - top;
}
}
}
void printhex(uint8_t text[8]) {
int i;
for(i = 0; i < 8; i++) {
printf("%02x", text[i]);
}
}
int main() {
uint8_t text[8] = "AAAAAAAA";
uint8_t text2[8] = "AAAAAAAA";
uint8_t key[8] = "AAAAAAAA";
puts("plaintext:");
printhex(text);
puts("\nkey:");
printhex(key);
puts("\n\nref encrypted:");
treyfer_encrypt(text, key);
printhex(text);
puts("\n\nencrypted:");
encrypt(text2, key);
printhex(text2);
puts("\n\ndecrypted:");
decrypt(text2, key);
printhex(text2);
puts("\n");
}
results
plaintext:
4141414141414141
key:
4141414141414141
ref encrypted:
cc3121ccab578d93
encrypted:
cc3121ccab578d93
decrypted:
4141414141414141

how to convert 2D to 1D array in C when int has hexadecimal

I have to change this code of 2D array to 1D array but i am not sure how to do it. Because the values of the 2D arrays are in hexadecimal.
int Sbox[SIZE_A][SIZE_B] = { //two dimensional array
{
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76
}, //* initializers for row indexed by 0
{
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf,
0x9c, 0xa4, 0x72, 0xc0
}, //* initializers for row indexed by 1
{
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1,
0x71, 0xd8, 0x31, 0x15
}, //* initializers for row indexed by 2
{
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75
}, {
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3,
0x29, 0xe3, 0x2f, 0x84
}, {
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39,
0x4a, 0x4c, 0x58, 0xcf
}, {
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8
}, {
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21,
0x10, 0xff, 0xf3, 0xd2
}, {
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d,
0x64, 0x5d, 0x19, 0x73
}, {
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb
}, {
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62,
0x91, 0x95, 0xe4, 0x79
}, {
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea,
0x65, 0x7a, 0xae, 0x08
}, {
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a
}, {
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
0x86, 0xc1, 0x1d, 0x9e
}, {
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9,
0xce, 0x55, 0x28, 0xdf
}, {
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16
}
};
I want to parse the exact values 0x63, 0x7c, 0x77, etc into the 1D array. So I thought of changing the int to string first, then read out the string as 0x63, 0x7c, 0x77, etc to the 1D array. Any help on how to do it?
The first thing you got to remember is that hexadecimal is just a way of presenting integer values, they are not stored as hexadecimal in the computer.
The second thing is that if you want to have a single array made out of a matrix, then the size of that single array would be (in your case) SIZE_A * SIZE_B entries big.
Then it's just a question of looping over the matrix, and setting the values in the array.
You can use the following code (both row-major and column-major order variants - please see comments in the code):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define A_SIZE 2
#define B_SIZE 3
int main() {
int values_2d[A_SIZE][B_SIZE] = {{0x12, 0x24, 0x46},{0x13,0x35, 0x57}};
int values_1d[A_SIZE*B_SIZE] = {0};
int i,j;
for (i = 0; i < A_SIZE; i++) {
for (j = 0; j < B_SIZE; j++) {
printf("v[%d,%d]=0x%02X\n", i, j, values_2d[i][j]);
}
}
for (i = 0; i < A_SIZE*B_SIZE; i++) {
values_1d[i] = values_2d[i/(B_SIZE)][i%B_SIZE]; // <<-- row-major order
//values_1d[i] = values_2d[i%A_SIZE][i/A_SIZE]; // <<-- column-major order
printf("values_1d[%d] = %d (0x%02X), values_2d[%d][%d] = %d (0x%02x)\n",
i, values_1d[i], values_1d[i],
i/B_SIZE, i%B_SIZE,
values_2d[i/B_SIZE][i%B_SIZE], values_2d[i/B_SIZE][i%B_SIZE]);
}
return 0;
}
Result:
┌─(55:55:55)─(michael#lorry)─(~/tmp/hex)
└─► gcc -o main main.c; ./main
values_1d[0] = 18 (0x12), values_2d[0][0] = 18 (0x12)
values_1d[1] = 36 (0x24), values_2d[0][1] = 36 (0x24)
values_1d[2] = 70 (0x46), values_2d[0][2] = 70 (0x46)
values_1d[3] = 19 (0x13), values_2d[1][0] = 19 (0x13)
values_1d[4] = 53 (0x35), values_2d[1][1] = 53 (0x35)
values_1d[5] = 87 (0x57), values_2d[1][2] = 87 (0x57)
It's is in Row-major order.
These are my codes. Is it ok?
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define SIZE_A 16 //width
#define SIZE_B 16 //heightint Sbox[SIZE_A][SIZE_B] = { //two dimensional array
{0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
0xfe, 0xd7, 0xab, 0x76}, //* initializers for row indexed by 0
{0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf,
0x9c, 0xa4, 0x72, 0xc0}, //* initializers for row indexed by 1
{0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1,
0x71, 0xd8, 0x31, 0x15}, //* initializers for row indexed by 2
{0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75},
{0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3,
0x29, 0xe3, 0x2f, 0x84},
{0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39,
0x4a, 0x4c, 0x58, 0xcf},
{0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
0x50, 0x3c, 0x9f, 0xa8},
{0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21,
0x10, 0xff, 0xf3, 0xd2},
{0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d,
0x64, 0x5d, 0x19, 0x73},
{0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
0xde, 0x5e, 0x0b, 0xdb},
{0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62,
0x91, 0x95, 0xe4, 0x79},
{0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea,
0x65, 0x7a, 0xae, 0x08},
{0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
0x4b, 0xbd, 0x8b, 0x8a},
{0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
0x86, 0xc1, 0x1d, 0x9e},
{0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9,
0xce, 0x55, 0x28, 0xdf},
{0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
0xb0, 0x54, 0xbb, 0x16}
};
int myarray[SIZE_A*SIZE_B]={0};
void print2darray(int Sbox[SIZE_A][SIZE_B])
{
int i,j;
for (i = 0; i < SIZE_A; i++ )
{
for (j = 0; j < SIZE_B; j++ )
{
printf("SBox[%d][%d] = 0x%02X\n",i,j,Sbox[i][j]);
}
}
for (i = 0; i < SIZE_A; i++ )
{
for (j = 0; j < SIZE_B; j++ )
{
myarray[i*SIZE_A+j]=Sbox[i][j];
int value=myarray[i*SIZE_B+j];
printf("myarray is [%d,%d] = 0x%02X\n",i,j,value);
}
}
return;
}
int main()
{
print2darray(Sbox);
return 0;
}
You can declare a pointer to int and allocate memory and convert as shown...
int i, j, k=0;
int *ptr = malloc(sizeof(*ptr) * SIZE_A * SIZE_B);
for(i = 0; i< SIZE_A; i++)
for(j = 0; j< SIZE_B; j++)
{
ptr[k++] = Sbox[i][j];
}
This should solve your problem, if you want the dimensions changed, switch the outer and inner loop
int array1D[SIZEA * SIZEB];
int index1D = 0;
for(int i = 0; i < SIZEB; ++i)
{
for(int j = 0; i < SIZEA; ++j)
{
array1D[index1D++] = Sbox[j][i];
}
}
Nishith was faster
Regarding: i am not sure how to do it. Because the values of the 2D arrays are in hexadecimal.
int Sbox[SIZE_A][SIZE_B] = {...
int Sbox is your first clue. Good news, No conversion necessary.
The numbers represented within each of these blocks are just integers, shown in hexidecimal format. Therefore, no conversion (i.e. from hex to int) is necessary, as they are already int. All you have to do is pick one of the approaches (described in another answer) to re-arrange the values.

Resources