I am working on a C module in micropython... if I pass a byte array to a function, only the first 8 bytes make it (according to sizeof). I have to also send in the length, then copy it to access everything in a function.
static void printSomeBytes(char *description, byte *bytes)
{
printf("\r\n%s: ", description);
for (int i = 0; i < sizeof(bytes); ++i )
{
printf("%02X", bytes[i]);
}
}
static void printAllBytes(char *description, byte *bytes, int length)
{
byte copy[length];
memcpy(copy, bytes, length);
printf("\r\n%s: ", description);
for (int i = 0; i < sizeof(copy); ++i )
{
printf("%02X", copy[i]);
}
// this also works without making a copy
//for (int i = 0; i < length; ++i )
//{
// printf("%02X", bytes[i]);
//}
}
byte Kifd[] = { 0x0B, 0x79, 0x52, 0x40, 0xCB, 0x70, 0x49, 0xB0, 0x1C, 0x19, 0xB3, 0x3E, 0x32, 0x80, 0x4F, 0x0B};
printSomeBytes("Kifd", kifd); // prints "Kifd: 0B795240CB7049B0"
printAllBytes("Kifd", kifd, sizeof(kifd)); // prints "Kifd: 0B795240CB7049B01C19B33E32804F0B"
What am I doing wrong / is there a better way to send a pointer to a byte array to a function?
sizeof(bytes) returns you the number of bytes that a pointer to byte will need to be stored in memory. It doesn't return you the number of bytes that the array pointed to by bytes contains.
For that you need to pass that size to the function:
static void printSomeBytes(char *description, byte *bytes, size_t size)
{
printf("\r\n%s: ", description);
for (size_t i = 0; i < size; ++i )
{
printf("%02X", bytes[i]);
}
puts("");
}
edit
I also added puts("") there so that the bytes are printed right away. Note
that printf is buffered and it won't show the output on the screen unless you flush it
(fflush(stdout);) by hand or add a '\n' newline at the end of printf.
puts(string) is equivalent to printf("%s\n", string); but without the
overhead of having to parse the format argument.
end edit
And then call it:
byte Kifd[] = { 0x0B, 0x79, 0x52, 0x40, 0xCB, 0x70, 0x49, 0xB0, 0x1C, 0x19, 0xB3, 0x3E, 0x32, 0x80, 0x4F, 0x0B};
printSomeBytes("Kifd", Kifd, sizeof Kifd / sizeof *Kifd);
Also the correct way of getting the number of elements of an array is:
sizeof array / sizeof *array
I encourage you to use that formula even when you know that the type is 8bit
long. It makes the code more portable.
You've done a poor job of explaining the issue. Are you saying that sizeof(bytes) returns 8?
bytes is a pointer, and sizeof(bytes) is returning the size of that pointer. And pointers may be 8 bytes on your system. That has nothing to do with the number of bytes at the address it points to.
In C, when you get a pointer, there is no way to know how many bytes it points to unless you provide that information as another argument or have a special terminating value in the data.
Related
I have method which accepts "constant char*" as a parameter. But when I pass the below array to the method "*SendUartMessage(int uartFd, const char dataToSend)**" only first two hexadecimal values are showing inside the method in the parameter. To be precise as the third value is zero 0x00, it blocks the other values pass inside the method. Can any one provide solution to pass all the array value inside the method.
const char updateAllChannelData[] = { 0x01, 0x06, 0x00, 0x19, 0x00, 0x01, 0x99, 0xCD };
SendUartMessage(uartFd, updateAllChannelData);
This is the method
static void SendUartMessage(int uartFd, const char* dataToSend)
{
size_t totalBytesSent = 0;
size_t totalBytesToSend = strlen(dataToSend);
int sendIterations = 0;
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_High);
while (totalBytesSent < totalBytesToSend) {
sendIterations++;
// Send as much of the remaining data as possible
size_t bytesLeftToSend = totalBytesToSend - totalBytesSent;
const char* remainingMessageToSend = dataToSend + totalBytesSent;
ssize_t bytesSent = write(uartFd, remainingMessageToSend, bytesLeftToSend);
if (bytesSent == -1) {
Log_Debug("ERROR: Could not write to UART: %s (%d).\n", strerror(errno), errno);
exitCode = ExitCode_SendMessage_Write;
return;
}
totalBytesSent += (size_t)bytesSent;
}
int c, d;
sleep(5);
close(r1PinFd);
r1PinFd = GPIO_OpenAsOutput(MIKROE_PWM, GPIO_OutputMode_PushPull, GPIO_Value_Low);
Log_Debug("Sent %zu bytes over UART in %d calls.\n", totalBytesSent, sendIterations);
}
The array has a 0 byte at index 2. strlen calculates the length of a C-string, that is, a null terminated (0 byte terminated) array. Treating your array as a string, the length is 2. If you want to know the real length of the array you have to pass it as a parameter:
const char updateAllChannelData[] = { 0x01, 0x06, 0x00, 0x19, 0x00, 0x01, 0x99, 0xCD };
SendUartMessage(uartFd, updateAllChannelData, sizeof(updateAllChannelData));
static void SendUartMessage(int uartFd, const char* dataToSend, size_t totalBytesToSend)
{
...
}
You're using strlen on a character array that is not a string.
Strings in C are null terminated, meaning a byte with value 0 ends the string. You don't have a string but an array of bytes whose valid values include 0.
You need to pass the size of the array to the function as a separate parameter.
Can any one provide solution to pass all the array value inside the method.
In C, when an array is passed to a function, the arrray is first converted to the type and address of the first element.
const char updateAllChannelData[] = {
0x01, 0x06, 0x00, 0x19, 0x00, 0x01, 0x99, 0xCD };
SendUartMessage(uartFd, updateAllChannelData);
SendUartMessage() receives a pointer to updateAllChannelData[0], not the array.
For SendUartMessage() to know how much of the array to use, also pass the array element count and re-write SendUartMessage() to accept the count.
static void SendUartMessage(int uartFd, size_t count, const char* dataToSend);
const char updateAllChannelData[] = {
0x01, 0x06, 0x00, 0x19, 0x00, 0x01, 0x99, 0xCD };
size_t count = sizeof updateAllChannelData / sizeof updateAllChannelData[0];
SendUartMessage(uartFd, count, updateAllChannelData);
I'm capturing fingerprints using a device called Secugen Pro 20, it has its own SDK for Linux, and i want to capture the fingerprint image and save it as any image format.
They have this typedef unsigned char BYTE;
I declared my imageBuffer
BYTE *CurrentImageBuffer;
Then i allocate memory to it using the devices specs
CurrentImageBuffer = malloc(device_info.ImageWidth*device_info.ImageHeight);
And at some point at my code i capture image and pass CurrentImageBuffer as argument to the capture function:
SGFPM_GetImageEx(m_hFPM, CurrentImageBuffer, GET_IMAGE_TIMEOUT, NULL, GET_IMAGE_DESIRED_QUALITY)
Thats what the variable looks right after this line of code ( i can confirm that it captured a finger):
I just don't understand how to proceed creating an image from this buffer, as it doesn't look like a ByteArray
I don't even know if thats the right place to get my image from, but that looks like the right place because its a buffer, right?.
OBS: I'm new to C
This is a small sample program to write an 8-bit graylevel image into a Windows BMP file:
#include <stdio.h>
typedef unsigned char Byte;
int writeBMPGray8(FILE *f, int w, int h, const Byte *data)
{
unsigned bytesPerRow = (w + 3) & ~3; // align to 4 bytes (requirement)
unsigned size
= 14 // Bitmap file header size
+ 12 // DIB header size
+ 256 * 3; // palette size
unsigned gap = size;
size = (size + 3) & ~3; // align to 4 bytes (requirement)
gap = size - gap; // get size of gap between end of headers and raw data
unsigned offs = size; // store offset of raw data
size += h * bytesPerRow; // bitmap data size in file
/* write Bitmap file header (14 bytes) */
{ const Byte buffer[14] = {
'B', 'M', // magic code
size & 0xff, size >> 8 & 0xff, size >> 16 & 0xff, size >> 24 & 0xff, // size of BMP file in bytes
0, 0, // reserved
0, 0, // reserved
offs & 0xff, offs >> 8 & 0xff, offs >> 16 & 0xff, offs >> 24 & 0xff // starting offset of pixel data
};
if (fwrite(buffer, sizeof buffer, 1, f) != 1) return -1; // ERROR!
}
/* write DIB header (12 bytes) */
{ const Byte buffer[12] = {
12, 0, 0, 0, // size of this header
w & 0xff, w >> 8 & 0xff, // bitmap width in pixels
h & 0xff, h >> 8 & 0xff, // bitmap height in pixels
1, 0, // number of color planes, must be 1
8, 0 // number of bits per pixel
};
if (fwrite(buffer, sizeof buffer, 1, f) != 1) return -1; // ERROR!
}
/* write color palette (3 * 256 bytes) */
for (int i = 0; i < 256; ++i) { // make a gray level palette
Byte buffer[3] = { i, i, i };
if (fwrite(buffer, sizeof buffer, 1, f) != 1) return -1; // ERROR!
}
/* write gap (to align start address of raw data with 4 */
for (int i = 0; i < gap; ++i) {
if (fputc(0, f) < 0) return -1; // ERROR!
}
/* write raw data */
for (int y = 0; y < h; ++y) { // for all rows
int x = 0;
for (; x < w; ++x) { // for all columns
if (fputc(*data++, f) < 0) return -1; // ERROR!
}
// write row padding
for (; x < bytesPerRow; ++x) {
if (fputc(0, f) < 0) return -1; // ERROR!
}
}
/* done */
return 0;
}
int main()
{
/* a sample image 6 x 8, gray level */
enum { w = 6, h = 8 };
const Byte imgRaw[w * h] = {
0x00, 0x30, 0x60, 0x90, 0xc0, 0xf0,
0x02, 0x32, 0x62, 0x92, 0xc2, 0xf2,
0x04, 0x34, 0x64, 0x94, 0xc4, 0xf4,
0x06, 0x36, 0x66, 0x96, 0xc6, 0xf6,
0x08, 0x38, 0x68, 0x98, 0xc8, 0xf8,
0x0a, 0x3a, 0x6a, 0x9a, 0xca, 0xfa,
0x0c, 0x3c, 0x6c, 0x9c, 0xcc, 0xfc,
0x0e, 0x3e, 0x6e, 0x9e, 0xce, 0xfe
};
FILE *f = fopen("test.bmp", "wb");
if (!f) return 1; // ERROR!
if (writeBMPGray8(f, w, h, imgRaw)) return 1; // ERROR!
if (fclose(f)) return 1; // ERROR!
return 0; // success
}
The sample image provides some kind of gradients horizontally and vertically. I've chosen a width of 6 intentionally to check/show that row alignment is done properly.
The implementation is based on the description in Wikipedia BMP file format.
To keep it short, I encoded the simplest format – the ancient BITMAPCOREHEADER of Windows 2.0 and OS/2 1.x. (MS Paint can load this as well as the Windows 10 preview. I tested with GIMP which loaded as well without any complaints.)
This is how it looks in GIMP:
The easiest way to get an image is to make a NetPBM PGM image - see Wikipedia NetPBM page.
So, if your image is say 640 px wide by 480 px tall, you would get a buffer from your SDK with 307,200 bytes and you would write that to a file and check it has the correct length. Call that image.raw.
Now you just need a PGM header, and as your image is greyscale and binary, you need a P5 header.
So, in Terminal you can put a header on:
{ printf "P5\n640 480\n255\n" ; cat image.raw ; } > image.pgm
If you are unfamiliar with that syntax, you can get the same with:
printf "P5\n640 480\n255\n" > image.pgm
cat image.raw >> image.pgm
And you can view that image with feh, gimp, Photoshop etc.
If you want to make it into a BMP, or JPEG, or PNG, use ImageMagick which is installed on most Linux distros and is available for macOS and Windows:
magick image.pgm image.png
or
magick image.pgm image.jpg
If your version of ImageMagick is v6 or older, use convert in place of magick:
convert image.pgm image.png
If you have correctly captured the image in CurrentImageBuffer, you can write this as raw file using the code fragment below:
fp = fopen(rawFileName,"wb");
fwrite (CurrentImageBuffer, sizeof (BYTE) , device_info.ImageHeight*device_info.ImageWidth , fp);
fclose(fp);
As I have used the same environment, I am sending the above fragment from my working codebase. Actually, raw file is later converted to template which is later used for matching / identification and not directly used for viewing etc. Variable rawFileName stores the name of the file as char array (string) where this buffer is stored.
This question already has answers here:
Initialization of C array at time other than declaration?
(7 answers)
Closed 5 years ago.
Not able to initialize the array in sequence. Actually, I want to construct the message with the length of 64. providing 64 array indexes, the code looks longer and verbose. I want to do it in sequence in order to avoid verbosity.
But I initialized an array like this buf[] and I tried as buf[6] also that didn't work either.
error: expected expression before ‘]’ token
Does anyone tell how to do it? Isn't it possible in C to initialize an array in different line not at declaration?
ARRAY_SIZE just give the count of array indexes.
Code:
void a_test(char in) {
uint8_t buf[256];
int i;
char cmd = in;
if (cmd == 'a') {
// it doesn't work like this
buf[] = { 0xfe, 0xb0, 0x01, 0x22, 0x00, 0x00};
/* it works like this
buf[0] = 0xfe;
buf[1] = 0xb0;
buf[2] = 0x01;
buf[3] = 0x22;
buf[4] = 0x00;
buf[5] = 0x00; */
}
if (cmd == 'b') {
buf[] = { 0x44, 0xb0, 0x01, 0x03, 0x00};
}
for (i = 0; i < ARRAY_SIZE(buf); i++) {
printf("%02x ", buf[i]);
}
}
int main() {
a_test('a');
return 0;
}
You can't use :
buf[] = { 0xfe, 0xb0, 0x01, 0x22, 0x00, 0x00};
except if it is in the declaration e.g:
uint8_t buf[]= { 0xfe, 0xb0, 0x01, 0x22, 0x00, 0x00};
Another way to pass all the values in one statement would be using memcpy:
memcpy(buf, (uint8_t[]) { 0xfe, 0xb0, 0x01, 0x22, 0x00, 0x00 }, sizeof (buf));
Arrays do not have the assignment operator but structures do have. So you can wrap an array in a structure.
That is you can do something like the following.
#include <stdio.h>
#include <stdint.h>
void a_test( char in )
{
struct Array
{
size_t n;
uint8_t buf[256];
} a = { 0 };
switch ( in )
{
case 'a':
a = ( struct Array ) { 6, { 0xfe, 0xb0, 0x01, 0x22, 0x00, 0x00 } };
break;
case 'b':
a = ( struct Array ) { 5, { 0x44, 0xb0, 0x01, 0x03, 0x00 } };
break;
}
for ( size_t i = 0; i < a.n; i++ )
{
printf( "%02x ", a.buf[i] );
}
putchar( '\n' );
}
int main(void)
{
a_test( 'a' );
a_test( 'b' );
return 0;
}
The program output is
fe b0 01 22 00 00
44 b0 01 03 00
I have an array of uint32_t. Each is value representing a Unicode characters. I want to print the array like a string but I'm not able to get that working.
I tried a lot of different things
typedef struct String {
uint32_t *characters;
unsigned long length;
} WRString;
char* WRStringToString(WRString *wstr){
char *string = malloc(sizeof(char) * wstr->length * 4);
int i = 0;
int j = 0;
for (; i < wstr->length; i++) {
string[j++] = wstr->characters[i];
char byte2 = (char)wstr->characters[i] >> 8;
if (byte2) {
string[j++] = byte2;
char byte3 = (char)wstr->characters[i] >> 16;
if (byte3) {
string[j++] = byte3;
char byte4 = (char)wstr->characters[i] >> 24;
if (byte4) {
string[j++] = byte4;
}
}
}
}
return string;
}
Always with
WRString *string; //Characters are 0xD6, 0x73, 0x74, 0x65, 0x72, 0x72, 0x65, 0x69, 0x63, 0x68
I tried:
setlocale(LC_CTYPE,"de_DE.UTF-8");
puts(WRStringToString(string));
Gives \326\377\377\377sterreich.
wprintf(L"%s",WRStringToString(string));
Gives the same as long as no local is set.
Printing UTF-8 strings with printf - wide vs. multibyte string literals and Printing Unicode Character (stored in variables) in C do not really help me.
Any suggestions?
Theses just seem to be unicode code points. Store them in a wchar_t string, one by one, and then print this with
printf("%ls\n", wstring);
You'd have to set the locale right at the start of your program to the default of the system:
set_locale(LC_ALL, "");
Jens Gustedt's answer was a point into the right direction but I keep using uint32_t, because I need to support Unicode's Emojis and wchar_t can be too small for those. (as said above by Remy Lebeau)
This seems to be working perfectly fine:
setlocale(LC_CTYPE,"de_DE.UTF-8");
printf("%ls\n", string->characters);
I have a program which takes the input data as a plaintext and then decrypts the message using 3DES method in CBC mode. But the values are hardcoded in the program I want to provide the encrypted value myself which should be decryted. How can I do this in the following program?
int main(void)
{
unsigned char in[BUFSIZE], out[BUFSIZE], back[BUFSIZE];
unsigned char *e = out;
int len;
DES_cblock key;
DES_cblock seed = {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10};
DES_cblock ivsetup = {0xE1, 0xE2, 0xE3, 0xD4, 0xD5, 0xC6, 0xC7, 0xA8};
DES_key_schedule keysched;
DES_cblock ivec;
memset(in, 0, sizeof(in));
memset(out, 0, sizeof(out));
memset(back, 0, sizeof(back));
RAND_seed(seed, sizeof(DES_cblock));
DES_random_key(&key);
DES_set_odd_parity(&key);
if (DES_set_key_checked((C_Block *)key, &keysched))
{
fprintf(stderr, "ERROR: Unable to set key schedule\n");
exit(1);
}
/* 64 bytes of plaintext */
/* From here, encryption starts for the plaintext below. */
strcpy(in, "Now is the time for all men to stand up and be counted");
printf("Plaintext: [%s]\n", in);
len = strlen(in);
memcpy(ivec, ivsetup, sizeof(ivsetup));
DES_ncbc_encrypt(in, out, len, &keysched, &ivec, DES_ENCRYPT);
printf("Ciphertext:");
while (*e) printf(" [%02x]", *e++);
printf("\n");
/* Till here, encryption is over. After this we have to decrypt
* the value which has been encoded, but I want to remove all this
* part and to provide my own encrypted message, and get the
* proper output.
*/
memcpy(ivec, ivsetup, sizeof(ivsetup));
/* The problem I am facing is how to provide the value properly
* to the parameter "out" and "keysched", which should be of my
* choice. For "out" I want to provide THIS value:
* "2DC39619B4450A8C27A3976C50DE5799".
*/
DES_ncbc_encrypt(out, back, len, &keysched, &ivec, DES_DECRYPT);
printf("Decrypted Text: [%s]\n", back);
exit(0);
}
Read more: http://blog.fpmurphy.com/2010/04/openssl-des-api.html#ixzz1uqOp1Yhv
Read C FAQ 20.10. Hexadecimal is a representation. All numbers are stored in binary internally. Your DES_cblock is probably a typedef for an (unsigned, perhaps!) integral type. So, what you have in effect is an array of integers. You can put numbers in decimal, hexadecimal or binary -- but they will all work. Hexadecimal is typically used in cryptography because it has some notational advantages.
I got it done.
I did it in a childish way for the time being but it is working now. I did it like this.
out[0]=0xA0; out[1]=0x69; out[2]=0x57; out[3]=0x3B;
out[4]=0x70; out[5]=0x26; out[6]=0x1C; out[7]=0xE8;
out[8]=0xEF; out[9]=0xF2; out[10]=0x9F;out[11]=0x60;
out[12]=0x80;out[13]=0x60;out[14]=0xB2;out[15]=0xE5;
Later I will do this thing in a for loop.
Create a dump function like this:
hexdump(char *buff, int len) {
int i,tmp;
for(i=0; i < len; i++) {
tmp = buff[i] & 0xff; /** to avoid sign extension */
printf("%02x",tmp);
}
}
And use it.
hexdump(back,len);
If you have to write it in memory, you can use sprintf, but you may have to write your own binary to hex function.
Using the nonstandard itoa function that stores the value it as a string, you can do the following:
char* hexstr = itoa(back,16);
// print out a string
printf("Decrypted Text: [%X]\n", back);