Mathematica Asked by toothandsticks on January 31, 2021
I am working with hexadecimal bytes but need to shift them into lists of binary bits for a few operations and then back again.
For example, I would like C12B to turn into {1,1,0,0,0,0,0,1,0,0,1,0,1,0,1,1} for evaluations, so BaseForm[c12b,16]
is out of the question for me, as far as I can tell.
Trying IntegerDigits[16^^C12B,2]
gets me what I need, but my problem is if I try to store the hex value as a variable for use in a function.
Let’s say I have a code:
hexToBinary[hexstring_]:=
Return[IntegerDigits[16^^hexstring,2]];
I realize I am no expert programmer, so there are probably small issues with this I cannot foresee, but 16^^hexstring
won’t evaluate, as it thinks "hexstring" is the number I am trying to evaluate and tells me the letters are too large for that number base. Additionally, the set delayed fails to work in this case, and the cell evaluates immediately, returning the error just described. In fact, hexstring never turns green inside the IntegerDigits part.
I ran Print[Head[c12b]]
earlier, and Mathematica told me it’s treating this as a "symbol."
I found out that if I input the hex in the form 0xc12b, Mathematica now thinks it’s an integer, but this doesn’t solve my problem of saving the value to a variable and then taking 16^^variable
.
Is there any feasible way around this? I am also going to have to turn the binary list back to Hex at some point, and I imagine I will run into similar problems on that end, but I have not gotten that far yet.
EDIT: If I make a function like Hausdorff suggested:
hexToBinary[hexstring_String] := IntegerDigits[FromDigits[hexstring,16],2];
Then that fixes my problem if and only if the hex value is put into this function as a string that has been saved under a variable, like:
input="c12b"
, followed by hexToBinary[input]
. But part of my question still exists: is there a way to save the hex value as an integer variable, like input=c12b
? Mathematica thinks c12b is another variable I have not yet defined if I try this.
The reason I ask this is not because I’m too lazy to put quotes around the strings but because I wanted to know if there is any way to do exactly what has been done here but without inputting it as a string in quotation marks. If I have to have the quotation marks, then so be it! The solution hints so far have been life-saving.
FromDigits
is fast but it does not catch invalid inputs.
IntegerDigits[FromDigits["C12BZ", 16], 2]
{1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1}
Interpreter
is slower but it will balk at invalid inputs.
IntegerDigits[Interpreter["HexInteger"]["C12BZ"], 2]
Answered by Suba Thomas on January 31, 2021
You cannot use the notation 16^^
with variable arguments, since it does not get "evaluated" like normal functions, but rather it is just a way of writing integers in different bases. For more information you can look at this question.
A way to implement what you want would be
hexToBinary[hexstring_String] := IntegerDigits[FromDigits[hexstring,16],2];
To turn the list of binaries back into hex, you could use
binaryToHex[binary_List] := IntegerString[FromDigits[binary,2],16];
So
hexToBinary["c12b"]
{1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1}
binaryToHex[{1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1}]
"c12b"
EDIT
As a workaround to allow simple user input you could use
hexToBinary[hex_] /; StringMatchQ[ToString[hex],RegularExpression["[A-Fa-f0-9]*"]] :=
IntegerDigits[FromDigits[ToString@hex,16],2];
hexToBinary[c12b]
{1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1}
Of course, this could cause problems if for example someone feeds in an already defined variable, but the StringMatchQ
should prevent at least some of them.
Answered by Hausdorff on January 31, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP