How to calculate modular multplication of array elements to integers in c? - c

Consider the following:
uint8_t message[15] = {
0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
};
uint64_t num = 0xa1b2c33412;
I want to multiply the above variable num to the array message[]. The pseudo-code for what I have need, is following:
uint8_t message[15] = {
0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
};
uint64_t num = 0xa1b2c33412;
uint64_t p = 0x31ba62ca3037;
uint64_t result = 0x00;
result = moduloMultiplication(message, num, p); // (message * num) (mod p)
I am expecting the following results:
num * msg = num*msg mod p
num * msg = 0x2bf2d18cdf92 (Final result)
Is there any way to multiply the array with value of typeuint64_t?
Any help regarding this will be appreciated...

Assuming the number stored in the 15-byte array is in big-endian order, here is a simple solution:
#include <stdio.h>
#include <stdint.h>
uint64_t moduloMultiplication(const uint8_t message[15], size_t n,
uint64_t num, uint64_t p)
{
uint64_t res = 0;
for (size_t i = 0; i < n; i++) {
// assuming `p < 1ULL << 56`
res = (res * 256 + message[i] * num) % p;
}
return res;
}
int main() {
uint8_t message[15] = {
0x32, 0xdc, 0x21, 0x55, 0x3f, 0x87, 0xc8, 0x1e,
0x85, 0x10, 0x43, 0xf9, 0x93, 0x34, 0x1a
};
uint64_t num = 0xa1b2c33412;
uint64_t p = 0x31ba62ca3037;
// result = (message * num) (mod p)
uint64_t result = moduloMultiplication(message, sizeof message, num, p);
printf("%#"PRIx64"\n", result);
return 0;
}
Output: 0x2bf2d18cdf92
The result differs from that in the question because either the message is incorrect, or your intermediary result is approximate: 201FF4CDCFE8C0000000000000000000000000000 seems incorrect.

Related

Plot Pixel of Hex Buffer

I have a Hex Code of an Image
static unsigned char Wallpaper[] = {
0xD9, 0x00, 0x00, 0xFF, 0xD9, 0x00, 0x00, 0xFF, 0xD9, 0x00, 0x00, 0xFF,
0xD9, 0x00, 0x00, 0x99, 0xD9, 0x05, 0x05, 0x02, 0xFF, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, /* skipped */
RGBAtoHex function :
unsigned long RGBAtoHex(int r, int g, int b, int a)
{
return ((a & 0xff) << 24) + ((r & 0xff) << 16) + ((g & 0xff) << 8) + (b & 0xff);
}
PlotPixel(x, y, hex /* 0xAARRGGBB */) function is surely right.
PlotPixel(x, y, colour)
{
*(uint32_t*)((uint64_t)TargetFramebuffer->BaseAddress + (x*4) + (y * TargetFramebuffer->PixelsPerScanLine * 4)) = colour;
}
void PlotPic()
{
uint32_t pos;
for (int y = 0; y < TargetFramebuffer->Height; y++)
{
for (int x = 0; x < TargetFramebuffer->Width; x++)
{
int r = Wallpaper[pos++];
int g = Wallpaper[pos++];
int b = Wallpaper[pos++];
int a = Wallpaper[pos++];
unsigned int pixel = RGBAtoHex(r, g, b, a);
PlotPixel(x, y, pixel);
}
}
}
I am tried to Plot the Pixels of this buffer with the Above code but failed, Output is :
So How can I get Right Pixels?
Note : I am using Graphics Output Protocol offered by UEFI Protocols.

Running code multiple times in a row has different results even with same input data

I need to convert a byte array to base58. I found the following function that is faster than using Bignums:
void EncodeAdrBase58(const uint8_t *bytes, unsigned char* result) //only accepts 25-byte arrays (1 byte for addressbyte, 20 for hash160, and 4 for checksum)
{
unsigned char digits[25 * 137 / 100];
int digitslen = 1;
for (int i = 0; i < 25; i++)
{
unsigned int carry = (unsigned int)bytes[i];
for (int j = 0; j < digitslen; j++)
{
carry += (unsigned int)(digits[j]) << 8;
digits[j] = (unsigned char)(carry % 58);
carry /= 58;
}
while (carry > 0)
{
digits[digitslen++] = (unsigned char)(carry % 58);
carry /= 58;
}
}
int resultlen = 0;
// leading zero bytes
for (; resultlen < 25 && bytes[resultlen] == 0;)
result[resultlen++] = '1';
// reverse
for (int i = 0; i < digitslen; i++)
result[resultlen + i] = ALPHABET[digits[digitslen - 1 - i]];
result[digitslen + resultlen] = 0;
}
When trying to test its speed I found that it gives the right answer- the first time. Then when running multiple times in a row with the same input data, it gives different answers. Oddly enough, those different answers are the same every time it's run. My testing method:
void encB58()
{
uint8_t data[] = { 0x00, 0x01, 0x09, 0x66, 0x77, 0x60, 0x06, 0x95, 0x3D, 0x55, 0x67, 0x43, 0x9E, 0x5E, 0x39, 0xF8, 0x6A, 0x0D, 0x27, 0x3B, 0xEE, 0xD6, 0x19, 0x67, 0xF6 };
unsigned char result[25 * 137 / 100];
for (int i = 0; i < 2; i++)
{
EncodeAdrBase58(&data, &result);
printf("%s\n", result);
}
}
If I run encB58(), I get
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
The first one is correct. If I change the loop in encB58() to 4 times, I get
16UwLL9Risc3QfPqBUvKofHmBQ7wMtjvM
1cXBanFJTEfPPbGcWw9Crh7mFGDvXmvSXuKs
12XoTKEDFdsWtAa7RJF7EvMJhdDv3EFu4VeS9
1FD5HoTinBXBszw6CoxPddSb6UkH3yvzYogZ
Also, if I change encB58() to use two different inputs and output to two different char arrays
void encB58()
{
uint8_t data[] = { 0x00, 0x01, 0x09, 0x66, 0x77, 0x60, 0x06, 0x95, 0x3D, 0x55, 0x67, 0x43, 0x9E, 0x5E, 0x39, 0xF8, 0x6A, 0x0D, 0x27, 0x3B, 0xEE, 0xD6, 0x19, 0x67, 0xF6 };
uint8_t data2[] = { 0x00, 0xED, 0xA9, 0x96, 0xA7, 0x21, 0x2D, 0x7D, 0xBB, 0x38, 0x22, 0xE8, 0x53, 0x20, 0x68, 0x91, 0x49, 0x95, 0x00, 0xDE, 0x4C, 0xD6, 0xB3, 0x5E, 0x9C };
unsigned char result[25 * 137 / 100];
unsigned char result2[25 * 137 / 100];
for (int i = 0; i < 2; i++)
{
EncodeAdrBase58(&data, &result);
EncodeAdrBase58(&data2, &result2);
printf("%s\n", result);
printf("%s\n", result2);
}
}
I get the following:
15uASzsR5JsK31Vs3ViKNV6fUM5T8TMp123AV
1rjdMG92vdQwp1bBmt3LpCnRyWaL9TzQ6Jbm
14g862Go94gqhyXQdndhKjZ5ZB8XeC3qqjiMT
1oBcJS1SK7taZQsGPXWYH2WEciL4EVzVRnfD
NONE of those are correct. What is happening here?

AES 256 program not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So I have been attempting to implement AES-256 in C. After lots of reading around and following the wikipedia page to implement it, I managed to code it. Only when I tested it, it seemed to give the wrong output.
Code:
/*
AES-256
(c) 2017 Daniel Gee
*/
#include <stdio.h>
#include <stdlib.h>
unsigned char 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
};
unsigned char 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
};
void rotate(unsigned char *w){
unsigned char t;
t = w[0];
w[0] = w[1];
w[1] = w[2];
w[2] = w[3];
w[3] = t;
}
void key_schedule_core(unsigned char *w, unsigned char i){
unsigned char j;
rotate(w);
for(j = 0; j < 4; j++){
w[j] = sbox[w[j]];
}
w[0] ^= rcon[i];
}
unsigned char *key_schedule(unsigned char *key){
unsigned char n = 32, b = 240, *e = malloc(sizeof(unsigned char) * b), i = 1, j, k, t[4];
for(k = 0; k < n; k++){
e[k] = key[k];
}
j = 32;
while(j < b){
t[0] = e[j - 4];
t[1] = e[j - 3];
t[2] = e[j - 2];
t[3] = e[j - 1];
key_schedule_core(t, i);
i++;
t[0] ^= e[j - n];
t[1] ^= e[j - n + 1];
t[2] ^= e[j - n + 2];
t[3] ^= e[j - n + 3];
e[j] = t[0];
e[j + 1] = t[1];
e[j + 2] = t[2];
e[j + 3] = t[3];
j += 4;
for(k = 0; k < 3; k++){
t[0] = e[j - 4];
t[1] = e[j - 3];
t[2] = e[j - 2];
t[3] = e[j - 1];
t[0] ^= e[j - n];
t[1] ^= e[j - n + 1];
t[2] ^= e[j - n + 2];
t[3] ^= e[j - n + 3];
e[j] = t[0];
e[j + 1] = t[1];
e[j + 2] = t[2];
e[j + 3] = t[3];
j += 4;
}
t[0] = e[j - 4];
t[1] = e[j - 3];
t[2] = e[j - 2];
t[3] = e[j - 1];
t[0] = sbox[t[0]];
t[1] = sbox[t[1]];
t[2] = sbox[t[2]];
t[3] = sbox[t[3]];
t[0] ^= e[j - n];
t[1] ^= e[j - n + 1];
t[2] ^= e[j - n + 2];
t[3] ^= e[j - n + 3];
e[j] = t[0];
e[j + 1] = t[1];
e[j + 2] = t[2];
e[j + 3] = t[3];
j += 4;
if(j > b){
break;
}
for(k = 0; k < 3; k++){
t[0] = e[j - 4];
t[1] = e[j - 3];
t[2] = e[j - 2];
t[3] = e[j - 1];
t[0] ^= e[j - n];
t[1] ^= e[j - n + 1];
t[2] ^= e[j - n + 2];
t[3] ^= e[j - n + 3];
e[j] = t[0];
e[j + 1] = t[1];
e[j + 2] = t[2];
e[j + 3] = t[3];
j += 4;
}
}
return e;
}
void shift_rows(unsigned char *state){
unsigned char t;
t = state[4];
state[4] = state[5];
state[5] = state[6];
state[6] = state[7];
state[7] = t;
t = state[8];
state[10] = t;
t = state[9];
state[11] = t;
t = state[12];
state[12] = state[15];
state[15] = state[14];
state[14] = state[13];
state[13] = t;
}
void mix_columns(unsigned char *state){
unsigned char a[4], b[4], c, j;
for(j = 0; j < 4; j++){
for(c = 0; c < 4; c++){
a[c] = state[(j * 4) + c];
b[c] = state[(j * 4) + c] << 1;
if(state[(j * 4) + c] & 0x80){
b[c] ^= 0x1b;
}
}
state[(j * 4) + 0] = b[0] ^ a[3] ^ a[2] ^ b[1] ^ a[1];
state[(j * 4) + 1] = b[1] ^ a[0] ^ a[3] ^ b[2] ^ a[2];
state[(j * 4) + 2] = b[2] ^ a[1] ^ a[0] ^ b[3] ^ a[3];
state[(j * 4) + 3] = b[3] ^ a[2] ^ a[1] ^ b[0] ^ a[0];
}
}
void encrypt(unsigned char *key, unsigned char *state){
unsigned char *e = key_schedule(key), i, j;
for(i = 0; i < 14; i++){
if(i == 0){
for(j = 0; j < 16; j++){
state[j] ^= e[(i * 16) + j];
}
}else if(i == 13){
for(j = 0; j < 16; j++){
state[j] ^= sbox[state[j]];
}
shift_rows(state);
for(j = 0; j < 16; j++){
state[j] ^= e[(i * 16) + j];
}
}else{
for(j = 0; j < 16; j++){
state[j] ^= sbox[state[j]];
}
shift_rows(state);
mix_columns(state);
for(j = 0; j < 16; j++){
state[j] ^= e[(i * 16) + j];
}
}
}
}
int main(){
unsigned char key[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
message[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
encrypt(key, message);
for(int i = 0; i < 16; i++){
printf("%02x ", message[i]);
}
printf("\n");
}
Example:
key = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
message = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
output = c2 2a 26 68 a8 4a 1e f3 ac 40 23 05 25 50 00 02
The book "The Design of Rijndael" (ISBN 3-540-42580-2) has a great list of test vectors in appendix D for all the intermediate steps of an AES 128 encryption. Step through your code and compare your results with those from the book. It should be easy to change your code temporarily to AES-128 to find the bugs and then switch it back to AES-256 afterwards.
After that, throw away your implementation and use an established implementation that has been thoroughly tested, since yours is vulnerable to timing attacks (because of the if(state[(j * 4) + c] & 0x80)), which allows an attacker to find out the secret key. To avoid this and other implementation bugs, consult a book about implementing cryptography and try to use as much preexisting code as possible instead of writing your own.

Drawing Fonts on screen in C

I emulated a screen with the SDL library. I want to draw fonts on this screen, simply using a "draw_pixel" function I already made.
I searched a lot on the Internet.
I found this website http://jared.geek.nz/2014/jan/custom-fonts-for-microcontrollers and the code works well. However it does not support variable-width characters
I only want to use source code.
Could you please tell me if there is a source code or a light library to draw fonts from pixels ?
EDIT : Here is my code I changed from M Oehm answer.
int DrawChar(char c, uint8_t x, uint8_t y, int r, int g, int b, SDL_Surface *rectangle, SDL_Surface *ecran, SDL_Rect position)
{
uint8_t i,j;
// Convert the character to an index
c = c & 0x7F;
if (c < ' ') {
c = 0;
} else {
c -= ' ';
}
const uint8_t* chr = font[c];
int w = chr[0];
chr++;
for (j = 0; j < w; j++) {
for (i = 0; i < CHAR_HEIGHT; i++) {
if (chr[j] & (1 << i)) {
draw_pixel(x+j, y+i, r, g, b, rectangle, ecran, position);
}
}
}
return w + CHAR_GAP;
}
void DrawString(const char* str, uint8_t x, uint8_t y, int r, int g, int b, SDL_Surface *rectangle, SDL_Surface *ecran, SDL_Rect position)
{
while (*str) {
x += DrawChar(*str++, x, y, r, g, b, rectangle, ecran, position);
}
}
const unsigned char font[96][6] = {
{3, 0x00, 0x00, 0x00}, //
{3, 0x00, 0x2f, 0x00}, // !
{4, 0x03, 0x00, 0x00, 0x03}, // "
Here is the result : The characters are still at the same size.
http://hpics.li/d54f000
EDIT :
The solution is here http://www.riuson.com/lcd-image-converter
You will have to change a bit the code because they are some mistakes, but it works.
You can easily extend the given code to variable-width characters. Change the definition of the font:
const unsigned char font[96][10] = {
{3, 0x00, 0x00, 0x00}, //
{3, 0x00, 0x2f, 0x00}, // !
{4, 0x03, 0x00, 0x00, 0x03}, // "
...
};
The first entry is the width of the character. The second dimension must be chosen to accomodate the widest character. It can be 9 pixels wide in this example.
Then extend the DrawChar function to use the given width and alo to return the width that the drwing position should advance, which is the width of the character plus a certain gap. (You can make the gap a parameter, so that you can print double-spaced text.)
The DrawString function then makes use of the returned width:
int DrawChar(char c, uint8 x, uint8 y, uint8 brightness)
{
uint8 i, j;
// Convert the character to an index
c = c & 0x7F;
if (c < ' ') {
c = 0;
} else {
c -= ' ';
}
const uint8* chr = font[c];
int w = chr[0];
chr++;
for (j = 0; j < w; j++) {
for (i = 0; i < CHAR_HEIGHT; i++) {
if (chr[j] & (1 << i)) {
DrawPixel(x + j, y + i, brightness);
}
}
}
return w + CHAR_GAP;
}
void DrawString(const char* str, uint8 x, uint8 y, uint8 brightness)
{
while (*str) {
x += DrawChar(*str++, x, y, brightness);
}
}
Edit: Here's a more complete example which defines only some letters:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef unsigned char uint8;
char screen[25][80];
#define CHAR_HEIGHT 8
#define CHAR_GAP 2
const unsigned char font[96][10] = {
[' ' - 32] = {1, 0x00},
['A' - 32] = {5, 0x3e, 0x09, 0x09, 0x09, 0x3e},
['B' - 32] = {5, 0x3f, 0x25, 0x25, 0x25, 0x19},
['D' - 32] = {5, 0x3f, 0x21, 0x21, 0x21, 0x1e},
['E' - 32] = {5, 0x3f, 0x25, 0x25, 0x25, 0x21},
['H' - 32] = {5, 0x3f, 0x04, 0x04, 0x04, 0x3f},
['I' - 32] = {1, 0x3f},
['L' - 32] = {4, 0x3f, 0x20, 0x20, 0x20},
['M' - 32] = {7, 0x3f, 0x02, 0x04, 0x18, 0x04, 0x02, 0x3f},
['O' - 32] = {5, 0x1e, 0x21, 0x21, 0x21, 0x1e},
['P' - 32] = {5, 0x3f, 0x09, 0x09, 0x09, 0x06},
['R' - 32] = {5, 0x3f, 0x09, 0x19, 0x19, 0x26},
['S' - 32] = {5, 0x22, 0x25, 0x25, 0x25, 0x19},
['W' - 32] = {7, 0x07, 0x38, 0x0c, 0x03, 0x0c, 0x38, 0x07},
};
void DrawPixel(int x, int y, uint8 c)
{
screen[y][x] = c;
}
int DrawChar(char c, uint8 x, uint8 y, uint8 brightness)
{
uint8 i, j;
// Convert the character to an index
c = c & 0x7F;
if (c < ' ') {
c = 0;
} else {
c -= ' ';
}
const uint8* chr = font[c];
int w = chr[0];
chr++;
for (j = 0; j < w; j++) {
for (i = 0; i < CHAR_HEIGHT; i++) {
if (chr[j] & (1 << i)) {
DrawPixel(x + j, y + i, brightness);
}
}
}
return w + CHAR_GAP;
}
void DrawString(const char* str, uint8 x, uint8 y, uint8 brightness)
{
while (*str) {
x += DrawChar(*str++, x, y, brightness);
}
}
int main()
{
int i;
memset(screen, '.', sizeof(screen));
DrawString("HELLO WORLD", 2, 2, 'O');
DrawString("MISSISSIPPI", 8, 10, '#');
for (i = 0; i < 25; i++) printf("%.80s\n", screen[i]);
return 0;
}

char array not displaying when passed to a function

Why is the passing of char array not showing?
The location of the pointer is passed to a function.
char plaintext[] = {
0xCD, 0x76, 0x43, 0xF0,
0x72, 0xA4, 0xA0, 0x82,
}
Given
void displayArray(char** plaintext, int size) {
// int newSize = sizeof(**plaintext);
int i;
for(i=0; i < size; ++i) {
printf("%02X ", (0xff & *plaintext[i]));
if (((i+1)% 8) == 0) // as index starts from 0, (i+1)
printf("\n");
}
}
in main()
char* plaintextCopy;
plaintextCopy = (char*) malloc(numberOfItems*sizeof(char));
memcpy(plaintextCopy, plaintext, numberOfItems);
displayArray(&plaintextCopy, numberOfItems);
Based on your code :
void displayArray(char** plaintext, int size)
{
int i;
for(i=0; i < size; i++)
{
printf("%02X ", (0xff & (*plaintext)[i]));
if(((i+1)% 8) == 0) // as index starts from 0, (i+1)
printf("\n");
}
}
int main(void)
{
char plaintext[] = {
0xCD, 0x76, 0x43, 0xF0,
0x72, 0xA4, 0xA0, 0x82,
};
int numberOfItems = sizeof(plaintext);
char* plaintextCopy;
plaintextCopy = (char*) malloc(numberOfItems*sizeof(char));
memcpy(plaintextCopy, plaintext, numberOfItems);
displayArray(&plaintextCopy, numberOfItems);
return 0;
}
It outputs :
CD 76 43 F0 72 A4 A0 82
Also, if you're sending an array that you want to display or change the values of, you don't need to send a double pointer to a function. A regular pointer would do. You should only use double pointers if the original array changes it's location in memory, that is, it's getting a new pointer after the function returns.

Resources