String to hex splitting - qt

I am having a QString :
QString str = "1000140035";
I want to extract each byte from above string like this :--
Unsigned char a = 0x10
Unsigned char b = 0x00
Unsigned char c = 0x14
Unsigned char d = 0x00
Unsigned char e = 0x35
Please suggest how to do this ... tried but failed many times.

QByteArray::fromHex + QString::toLatin1()
const QString str = "1000140035";
const QByteArray data = QByteArray::fromHex( str.toLatin1() );
unsigned char a = data[0];
unsigned char b = data[1];
unsigned char c = data[2];
unsigned char d = data[3];
unsigned char e = data[4];

You can use QString::toInt and set the base to 16 to convert a hex-string to int (or QString::toUInt).
QString str = "1000140035";
while(!str.isEmpty())
{
unsigned char byte = str.left(2).toInt(0, 16);
// do something with byte, store it somewhere or whatever...
str.remove(0, 2);
}

Perhaps this is what you're looking for? The code will parse an arbitrary length hexadecimal string and return an array of 2-digit hexadecimal numbers along with their count. It allocates memory for the result, so it is your responsibility to release it afterwards. The number of extracted numbers is returned through the third argument.
#include <QString>
#include <cmath>
unsigned HexToNum(char c)
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'A' && c <= 'F')
return 15 + c - 'A';
if(c >= 'a' && c <= 'f')
return 15 + c - 'a';
//Non hex char passed, return 0
return 0;
}
void ExtractBytes(const QString& hexString, unsigned char*& result, int& resultNumbersCount)
{
resultNumbersCount = static_cast<int>(ceil(hexString.length() / 2));
result = new unsigned char[resultNumbersCount];
int i, j = -1;
for(i = 0; i < resultNumbersCount; ++i)
result[i] = 0;
for(i = 0; i < hexString.length(); ++i)
{
if(i % 2 == 0)
++j;
result[j] = result[j] * 16 + HexToNum(hexString.at(i).toLatin1());
}
}

Related

Why does code not work after using fopen() command

I created FILE *ptr to read a file, and after I declare ptr =fopen("file_name.txt", "r");
none of my code written afterwards will work.
BELOW IS SOME OF THE ACTUAL CODE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define MAXFILE 30
#define MAX 50
typedef struct Student
{
int stdid;
char *fname;
char *lname;
int day;
int month;
int year;
}Student;
typedef struct Course
{
char *cid;
char *cname;
float credit;
}Course;
typedef struct Enrollment
{
int stdid;
int cid;
char *semester;
float score;
}Enrollment;
int main()
{
char stud[MAXFILE], courses[MAXFILE], enroll[MAXFILE];
printf("TESTING1");
scanf("%s %s %s",stud,courses,enroll);
int studnum,coursenum,enrollnum;
FILE *st, *cou, *enr;
st = fopen("stud","r");
cou = fopen("courses","r");
enr = fopen("enroll","r");
printf("TESTING2");
if(st==NULL || cou == NULL || enr== NULL)
{
printf("unable to open file\n");
exit(1);
}
fscanf(st,"%d",&studnum);
Student *students = (Student*)(malloc(sizeof(Student) * studnum));
for(int i =0; i<studnum;i++)
{
char ftemp[MAX],ltemp[MAX];
int fir, las;
fscanf(st,"%d %s %s %d %d %d",&students[i].stdid, ftemp, ltemp, &students[i].day, &students[i].month, &students[i].year);
fir = strlen(ftemp)+1;
las = strlen(ltemp)+1;
strcpy(students[i].fname,ftemp);
strcpy(students[i].lname,ltemp);
students[i].fname = malloc(fir * sizeof(char));
students[i].lname = malloc(las * sizeof(char));
strcpy(students[i].fname,ftemp);
strcpy(students[i].lname,ltemp);
}
//reading the students.txt file and filling out Student type array with data;
printf("TESTING3");
fscanf(cou,"%d",&coursenum);
Course *course = (Course*)(malloc(sizeof(Course)*coursenum));
for(int i =0; i<coursenum;i++)
{
char cidtemp[MAX], cntemp[MAX];
int tempcid, tempcn;
fscanf(cou,"%s %s %f",cidtemp, cntemp, &course[i].credit);
tempcid = strlen(cidtemp)+1;
tempcn = strlen(cntemp)+1;
course[i].cid = malloc(tempcid*sizeof(char));
course[i].cname = malloc(tempcn * sizeof(char));
strcpy(course[i].cid,cidtemp);
strcpy(course[i].cname, cntemp);
}
//reading the couses.txt file and filling out an array of type Course with the data
printf("TESTING4");
fscanf(enr,"%d",&enrollnum);
Enrollment *enrollment = (Enrollment*)(malloc(sizeof(Enrollment)*enrollnum));
for(int i =0; i<enrollnum; i++)
{
int stdid;
int cid;
char *semester;
float score;
char semest[MAX];
int semtemp;
fscanf(enr,"%d %d %s %f",&enrollment[i].stdid, &enrollment[i].cid, semest, &enrollment[i].score);
semtemp = strlen(semest)+1;
enrollment[i].semester = malloc(semtemp * sizeof(char));
strcpy(enrollment[i].semester, semest);
printf("%d\t%d\t%s\t%.0f \n", enrollment[i].stdid, enrollment[i].cid, enrollment[i].semester, enrollment[i].score);
}
//reading the enrollment files and fill out at array of type Enrollment
//testing new arrays
printf("%d", enrollnum);
for(int i = 0; i<enrollnum; i ++)
{
printf("%d\t%d\t%s\t%.0f \n", enrollment[i].stdid, enrollment[i].cid, enrollment[i].semester, enrollment[i].score);
}
fclose(st);
fclose(cou);
fclose(enr);
for(int i =0; i < studnum;i++)
{
free(students[i].fname);
free(students[i].lname);
}
free(students);
for(int i =0; i < coursenum;i++)
{
free(course[i].cid);
free(course[i].cname);
}
free(course);
for(int i =0; i < enrollnum;i++)
{
free(enrollment[i].semester);
}
free(enrollment);
return 0;
}

Freeing shows double free or corruption

typedef struct row_container
{
int size;
char *data;
}row_container;
typedef struct message_bar
{
char message[80];
time_t message_time;
}message_bar;
typedef struct brick_win_size
{
int row;
int col;
int current_row;
int current_column;
int data_row;
int row_off;
int col_off;
row_container *container;
char *filename;
message_bar *msg_bar;
}brick_window;
void container_delete_character(struct brick_win_size *win)
{
uint8_t insert_flag = 1;
int row = win->current_row;
int offset = win->current_column;
row_container *container = win->container;
char *data = container[row].data;
if(offset < container[row].size){
memmove(&data[offset], &data[offset + 1], container[row].size - 1);
data = realloc(data, container[row].size - 1);
container[row].data = data;
container[row].size--;
}
if(insert_flag){
if((container[row].size == 0) && (row < win->data_row)){
for(int index = row; index < win->data_row; index++){
if(index != win->data_row -1){
container[index] = container[index+1];
}else{
free(container[index]); //error line...............................
}
}
if(win->data_row != 0){
win->container = realloc(win->container, sizeof(row_container) * (win->data_row - 1));
win->data_row --;
}
}
}
}
Here in the above code i just want to delete one element at one point in the function. so i am just reassigning pointers with the other pointer and finally i am freeing the final element which is eventually ending up in build failure *expected ‘void ’ but argument is of type ‘row_container {aka struct row_container}’
Moreover if i give the & de reference operator it is ending up in double free or corruption error during execution

Update UDP checksum in fragmented packets

I'm building a network appliance. I need to support NAT and IP packet fragmentation. When I change the source or destination address of a UDP packet, I have to correct the UDP checksum (and the IP checksum too, but that's trivial). When the packet is fragmented, I'd have to collect all the fragments to recalculate the checksum. I know the old address and the new address. I'd like to:
Un-negate the checksum
Subtract the old address
Add the new address
Re-reduce the sum and negate
This process doesn't always work. Is there any way to update the checksum versus having to recalculate it from scratch?
I've tried:
long CalcCheckSumAdd(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum += *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum += *pbHeader;
return lSum;
}
long CalcCheckSumSubract(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum -= *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum -= *pbHeader;
return lSum;
}
unsigned short CalcCheckSumFinish(long lSum){
while (lSum >> 16){
lSum = (lSum & 0xFFFF) + (lSum >> 16);
}
return (unsigned short)(~lSum);
}
long CalcCheckSumUnfinish(unsigned short usSum){
// Can't totally undo lossy finish logic
return ~usSum;
}
unsigned short CalcCheckSumUpdateAddress(unsigned short usOldSum, unsigned long ulOldAddress, unsigned long ulNewAddress){
long lSumFixed = CalcCheckSumUnfinish(usOldSum);
lSumFixed = CalcCheckSumSubract((unsigned char*)&ulOldAddress,sizeof(ulOldAddress),lSumFixed);
lSumFixed = CalcCheckSumAdd((unsigned char*)&ulNewAddress,sizeof(ulNewAddress),lSumFixed);
return CalcCheckSumFinish(lSumFixed);
}
Thanks!
EDIT: Added unit test code below
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
long CalcCheckSumAdd(unsigned char *pbHeader, int iSize, long lInitial){
long lSum = lInitial;
while (iSize > 1){
lSum += *((unsigned short*)pbHeader);
pbHeader += 2;
iSize -= 2;
}
if (iSize > 0) lSum += *pbHeader;
return lSum;
}
unsigned short CalcCheckSumFinish(long lSum){
while (lSum >> 16){
lSum = (lSum & 0xFFFF) + (lSum >> 16);
}
return (unsigned short)(~lSum);
}
void Randomize(unsigned char *pucPacket, unsigned long ulSize){
for (unsigned long ulByte = 0; ulByte < ulSize; ulByte++){
pucPacket[ulByte] = (unsigned char)(255 * rand() / RAND_MAX);
}
}
unsigned short Calc(unsigned char *pucPacket, unsigned long ulSize){
long lSum = CalcCheckSumAdd(pucPacket,ulSize,0);
return CalcCheckSumFinish(lSum);
}
unsigned short Fix(unsigned short usOrig, unsigned int uiOld, unsigned int uiNew){
// TODO: Replace this with something that makes main never fail
usOrig -= uiOld & 0xffff;
usOrig -= uiOld >> 16 & 0xffff;
usOrig += uiNew & 0xffff;
usOrig += uiNew >>16 & 0xffff;
return usOrig;
}
void Break(unsigned char *pucPacket, unsigned int *puiOld, unsigned int *puiNew){
unsigned int *puiChange = (unsigned int*)pucPacket;
*puiOld = *puiChange;
Randomize((unsigned char*)puiNew,sizeof(unsigned int));
*puiChange = *puiNew;
}
void PrintBuffer(const char *szName, unsigned char *pucBuff, unsigned int uiSize){
printf("%s: ",szName);
for (unsigned int uiByte = 0; uiByte < uiSize; uiByte++){
printf("%02X",(unsigned int)pucBuff[uiByte]);
}
printf("\n");
}
void PrintTestCase(unsigned char *pucOrig, unsigned char *pucChanged, unsigned int uiSize, unsigned short usOrig, unsigned short usChanged, unsigned short usFixed){
PrintBuffer("Original Buffer",pucOrig,uiSize);
PrintBuffer("Changed Buffer ",pucChanged,uiSize);
printf("Orig checksum: %04X\n",(unsigned int)usOrig);
printf("Changed checksum: %04X\n",(unsigned int)usChanged);
printf("Fixed checksum: %04X\n",(unsigned int)usFixed);
}
int main(){
srand((unsigned int)time(nullptr));
unsigned char pucDataOrig[100];
unsigned char pucDataChanged[100];
bool bTestFailed = false;
while (!bTestFailed){
Randomize(pucDataOrig,sizeof(pucDataOrig));
memcpy(pucDataChanged,pucDataOrig,sizeof(pucDataOrig));
unsigned short usOrig = Calc(pucDataOrig,sizeof(pucDataOrig));
unsigned int uiOld = 0,
uiNew = 0;
Break(pucDataChanged,&uiOld,&uiNew);
unsigned short usFixed = Fix(usOrig,uiOld,uiNew);
unsigned short usChanged = Calc(pucDataChanged,sizeof(pucDataChanged));
if (usChanged == usFixed){
printf(".");
}else{
printf("\nTest case failed\n");
PrintTestCase(pucDataOrig,pucDataChanged,sizeof(pucDataOrig),usOrig,usChanged,usFixed);
bTestFailed = true;
}
}
return 0;
}
You are right, the solution above works only on some cases, but I have a new implem that works for all kind of packet (fragmented or not, UDP, TCP, IP). Here is the implem:
/* incremental checksum update */
static inline void
cksum_update(uint16_t *csum, uint32_t from, uint32_t to)
{
uint32_t sum, csum_c, from_c, res, res2, ret, ret2;
csum_c = ~((uint32_t)*csum);
from_c = ~from;
res = csum_c + from_c;
ret = res + (res < from_c);
res2 = ret + to;
ret2 = res2 + (res2 < to);
sum = ret2;
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
*csum = (uint16_t)~sum;
}
You can now use this function when you translated you packet address and before sending:
/* Update L4 checksums on all packet a part from [2nd, n] fragment */
switch (IS_FRAG(ipv4_hdr) ? 0 : ipv4_hdr->next_proto_id) {
case IPPROTO_TCP:
{
struct tcp_hdr *tcp_hdr = tcp_header(pkt);
/* Compute TCP checksum using incremental update */
cksum_update(&tcp_hdr->cksum, old_ip_addr, *address);
break;
}
case IPPROTO_UDPLITE:
case IPPROTO_UDP:
{
struct udp_hdr *udp_hdr = udp_header(pkt);
/* Compute UDP checksum using incremental update */
cksum_update(&udp_hdr->dgram_cksum, old_ip_addr, *address);
break;
}
default:
break;
}
You have to substract the old ip address and add the new one on the udp checksum, here is the pseudo code:
udp_hdr->dgram_cksum -= old_ipv4_addr & 0xffff;
udp_hdr->dgram_cksum -= old_ipv4_addr >> 16 & 0xffff;
udp_hdr->dgram_cksum += new_ipv4_addr & 0xffff;
udp_hdr->dgram_cksum += new_ipv4_addr >>16 & 0xffff;
That should handle UDP checksum on IP fragments.

how to tokenize a string in arduino

i am using arduino due. what i am trying to do is to receive a string at serial. like this one:
COMSTEP 789 665 432 END
if the string starts with comstep, then to tokenize the string and get an integer array {789, 665, 432}.
is there anyway to do that?
P.S: im a noob at programming, so any help is appreciated.
I have a function that I wrote long ago to parse strings up in an easy manner. It is in use on several of my Arduino projects.
Sample usage:
char pinStr[3];
char valueStr[7];
int pinNumber, value;
getstrfld (parms_in, 0, 0, (char *)",", pinStr);
getstrfld (parms_in, 1, 0, (char *)",", valueStr);
pinNumber = atoi (pinStr);
value = atoi (valueStr);
The functions:
// My old stand-by to break delimited strings up.
char * getstrfld (char *strbuf, int fldno, int ofset, char *sep, char *retstr)
{
char *offset, *strptr;
int curfld;
offset = strptr = (char *)NULL;
curfld = 0;
strbuf += ofset;
while (*strbuf) {
strptr = !offset ? strbuf : offset;
offset = strpbrk ((!offset ? strbuf : offset), sep);
if (offset) {
offset++;
} else if (curfld != fldno) {
*retstr = 0;
break;
}
if (curfld == fldno) {
strncpy (retstr, strptr,
(int)(!offset ? strlen (strptr)+ 1 :
(int)(offset - strptr)));
if (offset)
retstr[offset - strptr - 1] = 0;
break;
}
curfld++;
}
return retstr;
}
// Included because strpbrk is not in the arduino gcc/g++ libraries
// Or I just could not find it :)
char * strpbrk (const char *s1, const char *s2)
{
const char *c = s2;
if (!*s1) {
return (char *) NULL;
}
while (*s1) {
for (c = s2; *c; c++) {
if (*s1 == *c)
break;
}
if (*c)
break;
s1++;
}
if (*c == '\0')
s1 = NULL;
return (char *) s1;
}
A light-weight approach (no strict checks on valid parses of the integers and ignoring any list elements past a fixed maximum):
char buf[32] = "COMSTEP 789 665 432 END"; // assume this has just been read
int res[8], nres = 0;
bool inlist = false;
for (char *p = strtok(buf, " "); p; p = strtok(0, " "))
if (inlist)
{
if (!strcmp(p, "END"))
{
inlist = false;
break;
}
else if (nres < sizeof(res) / sizeof(*res))
res[nres++] = atoi(p);
}
else if (!strcmp(p, "COMSTEP"))
inlist = true;
if (!inlist)
for (size_t i = 0; i < nres; ++i)
printf("%d%s", res[i], i + 1 < nres ? " " : "\n"); // do whatever

Implementing Rc4 algorithm

I need to implement a Rc4 algorithm with a seed: 1 2 3 6 and the plain text cryptology. I am following this guideline we were provided in class, but it's not initializing S correctly.
my output is
and needs to be
My code was previously printing negative values , not sure why but I managed to fix that error. Thought everything was good to go but it's not. Sorry for the pictures, I figured it was easier to explain what I was following for my code structure. I am mod 4 the seed since it contains 4 characters, could that possibly be my error?
#include <iostream>
#include <string>
#include <string.h>
using std::endl;
using std::string;
void swap(unsigned int *x, unsigned int *y);
int main()
{
string plaintext = "cryptology";
char cipherText[256] = { ' ' };
unsigned int S[256] = { 0 };
unsigned int t[256] = { 0 };
unsigned int seed[4] = { 1, 2, 3, 6 }; // seed used for test case 1
unsigned int temp = 0;
int runningTotal = 0;
unsigned int key = 0;
// inilializing s and t
for (int i = 0; i < 256; i++)
{
S[i] = i;
t[i] = seed[i % 4];
}
for (int i = 0; i < 256; i++)
{
runningTotal += S[i] + t[i];
runningTotal %= 256;
swap(&S[runningTotal], &S[i]);
std::cout << S[i] <<" ";
}
runningTotal = 0;
for (int i = 0; i < plaintext.size(); i++)
{
runningTotal %= 256;
swap(&S[i], &S[runningTotal]);
temp = (unsigned int)S[i] + (unsigned int)S[runningTotal];
temp %= 256;
key = S[temp];
std::cout << endl;
cipherText[i] = plaintext[i] ^ key;
}
std::cout << " this is cipher text " << endl;
std::cout << cipherText << endl;
system("pause");
return 0;
}
void swap(unsigned int *x, unsigned int *y)
{
unsigned int temp = 0;
temp = *x;
*x = *y;
*y = temp;
}
Actually I think you're generating S[] correctly. I can only assume you're supposed to do something different with the key. (Perhaps's its an ASCII string instead of four byte values? Check your assignment notes.)
There is a problem later on, however. In the stream generation loop, you're supposed to do the increment and swap operations before you fetch a byte from S[].
for (int k = 0; k < plaintext.size(); k++)
{
i = (i+1) % 256; // increment S[] index
runningTotal = (runningTotal + S[i]) % 256; // swap bytes
swap(&S[i], &S[runningTotal]);
temp = (S[i] + S[runningTotal]) % 256; // fetch byte from S and
cipherText[k] = plaintext[k] ^ S[temp]; // XOR with plaintext
}
NOTE: Although unrelated to your question, your code could be made a lot tidier by using unsigned char values instead of ints. That would eliminate the % 256 instructions that are littered all over the place. (But be careful during initialization, because i<256 will always be true if i is an unsigned char.)

Resources