How to store int values in *pData and display values from it?
int id = 12;
int age = 14;
unsigned char* pData = new unsigned char[8];
memcpy(pData,&id,4);/* using memcpy to copy */
pData = pData + 4;
memcpy(pData,&age,4);/* using memcpy to copy */
// How to print value from buffer *pData
After using memcpy to copy the bytes of an int into an unsigned char buffer, the only correct way to display the ints is to copy the bytes back into an int. For example:
int temp_int;
memcpy(&temp_int, pData, sizeof temp_int);
std::cout << temp_int << '\n';
memcpy(&temp_int, pData + sizeof temp_int, sizeof temp_int);
std::cout << temp_int << '\n';
Attempting to reinterpret the buffer as an int would cause undefined behaviour by violating the strict aliasing rule.
you can change pData into int *, then you can print the int valve.
cout<<*((int *)pData);
memcpy(pData,&id,4);
This line copies the four bytes data in id to pData as int but you declared it as char * .
if you declare it as int *pData = new int[2]; then you can ptint exact values.
using namespace std;
int id = 12;
int age = 14;
unsigned int* pData = new unsigned int[2];
memcpy(pData,&id,4);
pData = pData + 1;
memcpy(pData,&age,4);
pData = pData - 1;
cout<<"ID:"<<pData[0]<<"\nAge:"<<pData[1]<<endl;
This will print the values.
If you really need to allocate memory as unsigned char*, you can do it like below:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
int id = 12;
int age = 14;
// const pointer to buffer which can contain 2 ints
unsigned char* const pData = new unsigned char[2*sizeof(int)];
// non-const pointer to operate on data
unsigned char* pDataPtr = pData;
memcpy(pDataPtr,&id,sizeof(int));
pDataPtr += sizeof(int);
memcpy(pDataPtr,&age,sizeof(int));
std::cout<<*reinterpret_cast<int*>(pData)<<std::endl;
std::cout<<*reinterpret_cast<int*>(pData + sizeof(int))<<std::endl;
delete [] pData;
return 0;
}
You can print pData using reinterpret_cast operator :
#include <iostream>
#include <cstring>
int main(void)
{
int id = 12;
int age = 14;
const size_t size = sizeof(int);
unsigned char* pData = new unsigned char[2*size];
memcpy(pData,&id,size);/* using memcpy to copy */
pData = pData + size;
memcpy(pData,&age,size);/* using memcpy to copy */
std::cout<<*reinterpret_cast<int*>(pData)<<std::endl;
pData = pData - size;
std::cout<<*reinterpret_cast<int*>(pData)<<std::endl;
delete []pData;
return 0;
}
Related
int computeHMACSHA1Hash(const char * unhashedcstr, char * hashedcstr, const char * key, int returncode)
{
string hashed;
size_t unhashlength = strlen(unhashedcstr);
char * nonconstunhashcstr = new char[unhashlength];
strcpy_s(nonconstunhashcstr, unhashlength + 1, unhashedcstr);
unsigned char* pixels = reinterpret_cast<unsigned char*>(nonconstunhashcstr);
returncode = 0;
HMAC_CTX* context = HMAC_CTX_new();
size_t unhashedstrlength = sizeof(unhashedcstr);
if (context != NULL)
{
if (HMAC_Init_ex(context, key, strlen(key), EVP_sha1(), NULL))
{
if (HMAC_Update(context, pixels, unhashedstrlength))
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int lengthOfHash = 0;
if (HMAC_Final(context, hash, &lengthOfHash))
{
std::stringstream ss;
for (unsigned int i = 0; i < lengthOfHash; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}
hashed = ss.str();
size_t outputSize = hashed.length() + 1; // +1 for null terminator
strcpy_s(hashedcstr, outputSize, hashed.c_str());
returncode = 0;
}
else
{
returncode = 7;
}
}
else
{
returncode = 6;
}
}
else
{
returncode = 5;
}
HMAC_CTX_free(context);
}
else
{
returncode = 4;
}
return returncode;
}
int main()
{
const char * unhashedcstr = "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={\"invoiceCode\": \"11111\",\"invoiceNo\": \"2222\",\"inTaxAmount\": \"\",\"exTaxAmount\": \"\"}";
char * hashedcstr = new char[100];
int returncode = 0;
const char * key = "SD886A11B0EE428F";
int result = computeHMACSHA1Hash(unhashedcstr, hashedcstr, key, returncode);
return 0;
}
I tried the code above to calculating the HMAC SHA1 hash value for a content, but compared the results on https://www.freeformatter.com/hmac-generator.html#before-output
it looks like I didn't do it right. I'm not sure what I have done wrong though. Any help would be appreciated.
It turned out the result was "d916b4c2d277319bbf18076c158f0cbcf6c3bc57", while on the website https://www.freeformatter.com/hmac-generator.html#before-output, the result was "71482b292f2b2a47b3eca6dad5e7350566d60963". Even when I tried using the string "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={"invoiceCode": "11111","invoiceNo": "2222","inTaxAmount": "","exTaxAmount": ""}" which removed the escape characters, the result was "09be98b6129c149e685ed57a1d19651a602cda0d". It didn't match the correct one.
Is there anything wrong with my code?
Your hash is calculated over the bytes a=se, which are the first four bytes of the whole input string. Thus, you get d916b4c2d277319bbf18076c158f0cbcf6c3bc57 instead of the 09be98b6129c149e685ed57a1d19651a602cda0d that would correspond to the whole string.
The reason is this:
size_t unhashedstrlength = sizeof(unhashedcstr);
Here, sizeof(unhashedcstr) is the size of the unhashedcstr pointer itself (which is of type const char*), not the size of the null-terminated C-style string this unhashedcstr pointer is pointing to. You are compiling a 32-bit program, so the size of a pointer is 4 bytes. Thus, unhashedstrlength is 4.
To get the length of the C-style string, you can do this instead:
size_t unhashedstrlength = strlen(unhashedcstr);
But just as a comment, in modern C++, you should avoid using raw pointers (such as const char*, char*, unsigned char*), C functions (like strlen(), strcpy_s()) and manual memory management (new / delete and new[] / delete[]). You should prefer to use std::string and/or std::vector<unsigned char> instead, wherever possible. When you need to pass a buffer's address to an API function, you can use std::string::data(), std::vector::data(), or more generally, std::data().
By the way, you currently leak memory: you dynamically allocate buffers using new[], but you never deallocate those (using delete[]). So that memory is released by the OS only after the program exits. This is called a memory leak.
I would like to copy a variable of 1 byte to relatively larger char array, and copy it back? How can I do that?
/* memcpy example */
#include <stdio.h>
#include <string.h>
struct Data {
unsigned char name[40];
int age;
};
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
int main ()
{
uint8_t myval = 8;
uint8_t myval_2 = 8;
Data mypass;
memcpy(&mypass.name, &myval, sizeof(uint8_t));
memcpy(&mypass.name+1, &myval_2, sizeof(uint8_t));
uint8_t* myvalnew = nullptr;
uint8_t* myvalnew_2 = nullptr;
memcpy(myvalnew, (uint8_t*)&mypass.name, sizeof(uint8_t));
memcpy(myvalnew_2, (uint8_t*)&mypass.name+1, sizeof(uint8_t));
return 0;
}
However I am getting errors.
&mypass.name creates a pointer to your name array, you want a pointer to the first element of your array, you can use either simply mypass.name or &mypass.name[0]. memcpy is unnecessary here as you can simply assign the elements:
mypass.name[0] = myval;
mypass.name[1] = myval_2;
Your second set of memcpys will fail as your myvalnew pointers are null, I'm not sure what you're trying to achieve here. If you're trying to get the values back you can again just use normal array access:
uint8_t myvalnew = mypass.name[0];
uint8_t myvalnew_2 = mypass.name[1];
I am trying to convert some C++ code to C for my compiler that can't run with C++ code. I'd like to create the template below to C. This template converts the decimal integer to hexadecimal, and adds 0 in front of value if the size of the hexadecimal string is smaller than (sizeof(T)*2). Data type T can be unsigned char, char, short, unsigned short, int, unsigned int, long long, and unsigned long long.
template< typename T > std::string hexify(T i)
{
std::stringbuf buf;
std::ostream os(&buf);
os << std::setfill('0') << std::setw(sizeof(T) * 2)
<< std::hex << i;
std::cout<<"sizeof(T) * 2 = "<<sizeof(T) * 2<<" buf.str() = "<<buf.str()<<" buf.str.c_str() = "<<buf.str().c_str()<<std::endl;
return buf.str().c_str();
}
Thank you for tour help.
Edit 1: I have tried to use the declaration
char * hexify (void data, size_t data_size)
but when I call with the int value int_value:
char * result = hexify(int_value, sizeof(int))
it doesn't work because of:
noncompetitive type (void and int).
So in this case, do I have to use a macro? I haven't tried with macro because it's complicated.
C does not have templates. One solution is to pass the maximum width integer supported (uintmax_t, in Value below) and the size of the original integer (in Size). One routine can use the size to determine the number of digits to print. Another complication is C does not provide C++’s std::string with is automatic memory management. A typical way to handle this in C is for the called function to allocate a buffer and return it to the caller, who is responsible for freeing it when done.
The code below shows a hexify function that does this, and it also shows a Hexify macro that takes a single parameter and passes both its size and its value to the hexify function.
Note that, in C, character constants such as 'A' have type int, not char, so some care is needed in providing the desired size. The code below includes an example for that.
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
char *hexify(size_t Size, uintmax_t Value)
{
// Allocate space for "0x", 2*Size digits, and a null character.
size_t BufferSize = 2 + 2*Size + 1;
char *Buffer = malloc(BufferSize);
// Ensure a buffer was allocated.
if (!Buffer)
{
fprintf(stderr,
"Error, unable to allocate buffer of %zu bytes in %s.\n",
BufferSize, __func__);
exit(EXIT_FAILURE);
}
// Format the value as "0x" followed by 2*Size hexadecimal digits.
snprintf(Buffer, BufferSize, "0x%0*" PRIxMAX, (int) (2*Size), Value);
return Buffer;
}
/* Provide a macro that passes both the size and the value of its parameter
to the hexify function.
*/
#define Hexify(x) (hexify(sizeof (x), (x)))
int main(void)
{
char *Buffer;
/* Show two examples of using the hexify function with different integer
types. (The examples assume ASCII.)
*/
char x = 'A';
Buffer = hexify(sizeof x, x);
printf("Character '%c' = %s.\n", x, Buffer); // Prints "0x41".
free(Buffer);
int i = 123;
Buffer = hexify(sizeof i, i);
printf("Integer %d = %s.\n", i, Buffer); // Prints "0x00007b".
free(Buffer);
/* Show examples of using the Hexify macro, demonstrating that 'A' is an
int value, not a char value, so it would need to be cast if a char is
desired.
*/
Buffer = Hexify('A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x00000041".
free(Buffer);
Buffer = Hexify((char) 'A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x41".
free(Buffer);
}
You don't need templates if you step down to raw bits and bytes.
If performance is important, it is also best to roll out the conversion routine by hand, since the string handling functions in C and C++ come with lots of slow overhead. The somewhat well-optimized version would look something like this:
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
This breaks down any passed type byte-by-byte, using a character type. Which is fine, when using character types specifically. It also uses caller allocation for maximum performance. (It can also be made endianess-independent with an extra check per loop.)
We can make the call a bit more convenient with a wrapper macro:
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
Full example:
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
int main (void)
{
char buf[50];
int32_t i32a = 0xABCD;
puts(hexify(buf, i32a));
int32_t i32b = 0xAAAABBBB;
puts(hexify(buf, i32b));
char c = 5;
puts(hexify(buf, c));
uint8_t u8 = 100;
puts(hexify(buf, u8));
}
Output:
0000ABCD
AAAABBBB
05
64
an optional solution is to use format string like printf
note that you can't return pointer to local variable, but you can get the buffer as argument, (here it is without boundaries check).
char* hexify(char* result, const char* format, void* arg)
{
int size = 0;
if(0 == strcmp(format,"%d") || 0 == strcmp(format,"%u"))
{
size=4;
sprintf(result,"%08x",arg);
}
else if(0 == strcmp(format,"%hd") || 0 == strcmp(format,"%hu"))
{
size=2;
sprintf(result,"%04x",arg);
}
else if(0 == strcmp(format,"%hhd")|| 0 == strcmp(format,"%hhu"))
{
size=1;
sprintf(result,"%02x",arg);
}
else if(0 == strcmp(format,"%lld") || 0 == strcmp(format,"%llu") )
{
size=8;
sprintf(result,"%016x",arg);
}
//printf("size=%d", size);
return result;
}
int main()
{
char result[256];
printf("%s", hexify(result,"%hhu", 1));
return 0;
}
I am using 'pBuff' as pointer and put a char array in function 'myfunc'.
So, In main function, I should receive it in aBuff.
But it is not working.. what is wrong here ??
#include <stdio.h>
void myfunc(void *pBuff, int &i);
int main()
{
int len;
char aBuff[2]={0};
printf("Hello World");
myfunc(aBuff,len);
printf("aBuff %s", aBuff);
return 0;
}
myfunc(void *pBuff, int &i){
char a[2] = {'a', 'b'};
i = 5;
pBuff = &a;
}
char a[] should come as output parameter in main function
You are passing a pointer to your function, inside your function you assign the address of the temporary variable a to the pBuff variable. The original aBuff variable is unaffected.
As we are using c++ a much simpler solution using strings would be:
#include <iostream>
void myfunc(std::string& pBuff, int &i);
int main()
{
int len;
std::string aBuff;
std::cout << "Hello World";
myfunc(aBuff,len);
std::cout << "aBuff " << aBuff;
return 0;
}
void myfunc(std::string& pBuff, int &i){
pBuff = "ab";
i = 5;
}
If you really must use raw character arrays then this would be one way to implement it (note the removal of the void*, no reason to use it here):
myfunc(char *pBuff, int &i){
strcpy(pBuff, "ab");
i = 5;
}
If you need to store 2 characters in your aBuff array it needs to be 3 characters long not 2 as you need to leave space for the null terminator otherwise printf and other string functions will not work correctly.
If you want to return an array you have several possible solutions:
Pass a pointer (type*) to the function and copy the data unsing e.g. memcpy. You should also pass the size of the destination array and make sure you don't copy too much data.
Pass a reference to the pointer (type *&) and assign to the pointer in the function
Pass the address of the pointer (type**) and assign the address to the dereferenced pointer.
You must not return the address of a local variable with automatic storage. If you want to return a (which is a pointer to the first element) from the function it must be either static or dynamically allocated using e.g. malloc.
Which solution to choose depends on your needs:
Examples for 3 variants:
#include <stdio.h>
#include <memory.h>
void myfunc(char **pBuff, int &i);
void myfunc2(char *&pBuff, int &i);
void myfunc1(char *pBuff, size_t bufsize, int &i);
int main()
{
int len;
char aBuff[3]={0}; // increased size for NUL termination
char *ptr = aBuff;
printf("Hello World");
myfunc(&ptr,len);
printf("ptr %s", ptr);
printf("\n");
myfunc2(ptr,len);
printf("ptr %s", ptr);
printf("\n");
myfunc1(aBuff, sizeof aBuff,len);
printf("aBuff %s", aBuff);
return 0;
}
void myfunc1(char *pBuff, size_t bufsize, int &i){
char a[3] = {'c', 'd', '\0'}; /* added '\0' to allow using it as a string */
i = 5;
// actually the minimum of bufsize and sizeof(a) should be used
memcpy(pBuff, a, bufsize);
}
void myfunc(char **pBuff, int &i){
static char a[3] = {'a', 'b', '\0'}; // added '\0' to allow using it as a string
i = 5;
*pBuff = a;
}
void myfunc2(char *&pBuff, int &i){
static char a[] = "xyz";
i = 5;
pBuff = a;
}
I want to convert:
A simple unsigned char [] to string
Then again to unsigned char
This is my code:
// This is the original char
unsigned char data[14] = {
0x68,0x65,0x6c,0x6c,0x6f,0x20,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
};
// This convert to string
string str(data, data + sizeof data / sizeof data[0]);
// And this convert to unsigned char again
unsigned char* val = new unsigned char[str.length() + 1];
strcpy_s(reinterpret_cast<char *>(val), str.length()+1 , str.c_str());
The problem is with the 2nd part, It wont convert the string to unsigned char like it was before. I think this img from locals in debug helps
One way:
#include <string>
#include <utility>
#include <cstring>
#include <memory>
#include <cassert>
int main()
{
// This is the original char
unsigned char data[14] = {
0x68,0x65,0x6c,0x6c,0x6f,0x20,0x63,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,
};
// This convert to string
std::string str(std::begin(data), std::end(data));
// And this convert to unsigned char again
auto size = std::size_t(str.length());
auto new_data = std::make_unique<unsigned char[]>(size);
std::memcpy(new_data.get(), str.data(), size);
// check
for (auto f1 = data, f2 = new_data.get(), e1 = f1 + size ; f1 != e1 ; ++f1, ++f2)
{
assert(*f1 == *f2);
}
}