Visit Jeremy's Blog.
 Home Forums HCL Reviews Tutorials Articles Register Search Today's Posts Mark Forums Read
 LinuxQuestions.org [SOLVED] The best way to perform bitwise operation on hexadecimal value ?
 Programming This forum is for all programming questions. The question does not have to be directly related to Linux and any language is fair game.

Notices

 05-15-2014, 01:53 PM #1 kikilinux Member   Registered: Sep 2012 Posts: 125 Rep: The best way to perform bitwise operation on hexadecimal value ? Hi The problem is :i have a hex value just like bellow: unsigned char * temp = "\x4b001cdb3349" ok now i want to set specific bit of this string (change that bit to 1) in C. I know many ways are exist to do that but maybe the way i choose has unnecessary overhead. I can read the first byte (4b) convert to decimal value and do OR with the value that its bits is set to 1 (this could be a one solution). but any other suggestion ?
 05-15-2014, 02:19 PM #2 suicidaleggroll LQ Guru Contributing Member   Registered: Nov 2010 Location: Colorado Distribution: OpenSUSE, CentOS Posts: 5,481 Rep: That's not a hex value, it's a string. Are you trying to set a bit in the string, or are you trying to read two characters in the string as a single hex byte, set a bit in that, and then convert back to a pair of characters and insert it back into the string? For example, take the string "4a" If you interpret the characters in this string as two hex values, you get the decimal number 74, and the binary number 01001010. If you want to set the fifth bit, you would get 01011010, or decimal number 90, or hex number 5a. Then you could convert this back to the string "5a". On the other hand, if you set the fifth bit in your string, you get a very different answer. The ASCII characters "4a" are the hex numbers 34 and 61 respectively (52 and 97 in decimal). This converts to the binary numbers 00110100 and 01100001. If you set the fifth bit here, you get 00110100 and 01110001, 34 and 71 in hex, 52 and 113 in decimal, which maps back to the ASCII characters "4q". Last edited by suicidaleggroll; 05-15-2014 at 02:31 PM. 2 members found this post helpful.
 05-15-2014, 03:29 PM #3 sundialsvcs LQ Guru   Registered: Feb 2004 Location: SE Tennessee, USA Distribution: Gentoo, LFS Posts: 8,204 Blog Entries: 4 Rep: Okay, with a little finagling you should be able to sccanf() that string-value using an appropriate format-string to get your binary number. (A longint, looks like.) Then, you can perform the bitwise operations against that. First, convert the value and store it in a longint variable. Trap any exceptions that occur, and deal with them appropriately.) Then, mash the bits.
 05-15-2014, 03:52 PM #4 metaschima Senior Member   Registered: Dec 2013 Distribution: Slackware Posts: 1,982 Rep: You need to be more specific about the problem you have. Provide working code and then we will see. To change one bit of a certain variable you can use a mask and the | (logical or) operator. This is the usual way to do it, but your code doesn't make sense. Code: ```bash-4.2\$ cat str.c #include int main (void) { unsigned char * temp = "\x4b001cdb3349"; printf ("%s\n", temp); return 0; } bash-4.2\$ compile str.c str.c: In function 'main': str.c:5:26: warning: hex escape sequence out of range [enabled by default] unsigned char * temp = "\x4b001cdb3349"; ^ str.c:5:26: warning: pointer targets in initialization differ in signedness [-Wpointer-sign] bash-4.2\$ ./str I``` If you had an actual string, you would have to convert it using scanf() or atoi().
05-15-2014, 07:20 PM   #5
jailbait
LQ Guru

Registered: Feb 2003
Location: Blue Ridge Mountain
Distribution: Linux Mint 17, Debian 8
Posts: 7,860

Rep:
Quote:
 Originally Posted by kikilinux I can read the first byte (4b) convert to decimal value and do OR with the value that its bits is set to 1 (this could be a one solution). but any other suggestion ?
Do the bit twiddling in hex, not decimal. You can do anything you want to a bit with AND, OR, and XOR and using the appropriate mask.

-----------
Steve Stites

1 members found this post helpful.
05-16-2014, 02:41 AM   #7
Syndacate
LQ Newbie

Registered: Aug 2008
Location: Santa Clara, CA
Distribution: Ubuntu, mainly. Too much stuff works out of the box O.o
Posts: 27

Rep:
Quote:
 Originally Posted by kikilinux unsinged char * temp; unsigned char * insertByte; // some code temp = kmalloc(ip_header->ihl * 4, GFP_KERNEL); memcpy(temp, ip_header , ip_header->ihl * 4); insertByte = kmalloc(sizeof(char), GFP_KERNEL); insertByte = "\x01"; *(temp + 20) = *(temp + 20) | *insertByte; This code set the first bit of Twentieth-first byte to 1 in temp variable but i want to perform this operation on same byte of the IP header directly. any suggestion would be greatly appreciated.
Okay, so maybe I'm not understanding the problem in its entirety (I don't do well w/o pix :-P). Though if you want to set the 21st byte in the IP header to 1 (ie 0000 0001), then you should be able to do it with something like this (untested, but should work):
I'm assuming "ip_header" is local, and not a ptr...if it's a ptr just remove the ampersand.
Code:
```char *ip_hdr_ptr = (char*)&ip_header;
*(ip_hdr_ptr + 20) = 1;```
No need to copy it into a temp variable, just set it directly in the ip_header.

Maybe I'm misunderstanding something about what you're trying to do (probably the case, lol).

EDIT:
Note that you should use "uint8_t" instead of "char" for stuff like this, as uint8_t is guaranteed to be 8 bits, char is not (ie. unicode). Makes the code a bit more portable. Also note that (especially with IP stuff) that this may not be endian safe.

Last edited by Syndacate; 05-16-2014 at 02:44 AM.

2 members found this post helpful.
 05-16-2014, 12:43 PM #8 kikilinux Member   Registered: Sep 2012 Posts: 125 Original Poster Rep: Dear Syndacate thanks to answer, it is not completely same but ur solution is work for me. I want the to set a specific bit of specific byte for example "first bit of 21st byte". i problem solved. Best
 05-16-2014, 01:10 PM #9 kikilinux Member   Registered: Sep 2012 Posts: 125 Original Poster Rep: Lets i illustrate what i want to do. For example, this is the ip header : "00 4c .... 0a 04 00 00" Lets assume the last fourth bytes are 21st to 24st bytes of ip header. Then i want to set second bit of 22st byte to 1. struct iphdr *ip_header; unsigned char * temp; unsigned char * insertByte; temp = kmalloc(ip_header->ihl * 4, GFP_ATOMIC); insertByte = kmalloc(sizeof(char), GFP_ATOMIC); temp = (unsigned char *)ip_header; // Adjust temp to point to ip header insertByte = "\x02"; *(temp + 22) = *(temp + 22) | *insertByte; Does my programming accurate ? Any suggestion to improve the code ?
 05-16-2014, 01:16 PM #10 suicidaleggroll LQ Guru Contributing Member   Registered: Nov 2010 Location: Colorado Distribution: OpenSUSE, CentOS Posts: 5,481 Rep: I would replace insertByte with just 1<
 05-16-2014, 01:35 PM #11 kikilinux Member   Registered: Sep 2012 Posts: 125 Original Poster Rep: woooow I don't know programming at all. Thanks to answer. I have to work a lot on my programing skill. Best
05-16-2014, 02:38 PM   #12
ntubski
Senior Member

Registered: Nov 2005
Distribution: Arch
Posts: 3,136

Rep:
Code:
```temp = kmalloc(ip_header->ihl * 4, GFP_ATOMIC);
...
This is a memory leak, you're throwing away the value returned from kmalloc().

Quote:
 Originally Posted by suicidaleggroll where N is the bit you want to set minus 1
Or just number the bits from 0, like God intended.

 05-16-2014, 03:20 PM #13 kikilinux Member   Registered: Sep 2012 Posts: 125 Original Poster Rep: Lets i fixed the errors; 1 - i don't need to allocate any memory to temp variable and at the end of program kfree(insertByte) or 2 - just kfree temp and insertByte do i am correct ?
05-16-2014, 04:55 PM   #14
ntubski
Senior Member

Registered: Nov 2005
Distribution: Arch
Posts: 3,136

Rep:
Quote:
 Originally Posted by kikilinux 1 - i don't need to allocate any memory to temp variable and at the end of program kfree(insertByte)
If you follow suicidaleggroll's advice you don't need to allocate insertByte either.

Quote:
 or 2 - just kfree temp and insertByte
You can't kfree temp once you have overwritten the original value that came from kmalloc.

 05-16-2014, 05:03 PM #15 Chickentree LQ Newbie   Registered: Feb 2012 Posts: 5 Rep: Would it not be better to use a standard header with the defines available there? On my Debian system that would appear to be /usr/include/netinet/ip.h. That header seems to define the available fields and flags and would make the purpose of your code much clearer.

 Tags bits, programming

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is Off HTML code is Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post dgashu Programming 3 01-31-2013 09:48 AM ananth86coolguy Linux - Newbie 4 03-13-2009 09:59 AM Brynn Linux - Newbie 6 07-24-2006 06:02 AM johndoe0028 Linux - General 6 04-02-2006 10:39 PM eshwar_ind Programming 17 10-25-2004 02:13 AM

All times are GMT -5. The time now is 12:42 PM.

 Contact Us - Advertising Info - Rules - LQ Merchandise - Donations - Contributing Member - LQ Sitemap -