How to create python bytes object from long hex string?
Solution 1
result = bytes.fromhex(some_hex_string)
Solution 2
Works in Python 2.7 and higher including python3:
result = bytearray.fromhex('deadbeef')
Note: There seems to be a bug with the bytearray.fromhex()
function in Python 2.6. The python.org documentation states that the function accepts a string as an argument, but when applied, the following error is thrown:
>>> bytearray.fromhex('B9 01EF')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fromhex() argument 1 must be unicode, not str`
Solution 3
You can do this with the hex codec. ie:
>>> s='000000000000484240FA063DE5D0B744ADBED63A81FAEA390000C8428640A43D5005BD44'
>>> s.decode('hex')
'\x00\x00\x00\x00\x00\x00HB@\xfa\x06=\xe5\xd0\xb7D\xad\xbe\xd6:\x81\xfa\xea9\x00\x00\xc8B\x86@\xa4=P\x05\xbdD'
Solution 4
Try the binascii module
from binascii import unhexlify
b = unhexlify(myhexstr)
Solution 5
import binascii
binascii.a2b_hex(hex_string)
Thats the way I did it.
Related videos on Youtube
J Seabolt
Updated on July 08, 2022Comments
-
J Seabolt almost 2 years
I am building an application on Rails where a user creates a Test, goes to the show view for that test and fills in a form with an answer to a question. If the answer to the question matches the "correct_answer" (defined in the controller), there will be flash message that the answer was correct and a button to continue to the root_path will appear. If the answer is wrong, the flash says "Wrong answer."
My problem is that the flash message will say wrong answer even if no answer has been given. I ONLY want that message to appear AFTER the user has submitted the form. I understand why this is happening, I just am unsure about how to fix it. Here is the show view for a test:
<div class="col-md-8 col-md-push-2"> <h4>Current Score: <%= @test.score %></h4> <br /><br /> <div class="form_group"> <%= form_tag test_path(@test), :method=> 'get' do %> <h4>What is my first name?</h4> <div class="form-group"> <%= text_field_tag :answer, params[:answer], class: 'form-control' %> </div> <% if !flash[:success] %> <div class="form-group"> <%= submit_tag "Submit", class: "btn btn-primary" %> </div> <% end %> <% end %> </div> <% if flash[:success] %> <%= link_to "Continue", root_path, class: "btn btn-success pull-right" %> <% end %> </div>
Here is the controller for tests, which contains the offending show action:
class TestsController < ApplicationController def index @test = Test.new @tests = Test.all end def show @test = Test.find(params[:id]) correct_answer = "jack" user_answer = params[:answer] if user_answer == correct_answer flash.now[:success] = "That is correct!" new_score = @test.score += 1 @test.update(score: new_score) elsif params[:answer] != correct_answer flash.now[:danger] = "Wrong answer" end end def create @test = Test.create(test_params) if @test.save redirect_to test_path(@test) flash[:success] = "Test created" else flash[:danger] = "There was a problem" render "index" end end def destroy @test = Test.find(params[:id]) if @test.destroy flash[:success] = "Your test was removed" redirect_to root_path end end private def test_params params.require(:test).permit(:score, :user_id) end end
Is there a better way to do this? If not, can I somehow stop the flash message from appearing on the initial load? I ONLY want it to appear once the form has been submitted. Thanks in advance.
-
Paul Hoffman over 10 yearsNote that the answers below may look alike but they return different types of values. s.decode('hex') returns a str, as does unhexlify(s). bytearray.fromhex(s) returns a bytearray. Given the wording of this question, I think the big green checkmark should be on bytearray.fromhex(s), not on s.decode('hex').
-
Ciro Santilli OurBigBook.com almost 7 yearsPossible duplicate of hexadecimal string to byte array in python
-
B Bulfin almost 7 yearsHow can it be a duplicate of a question created 2 years later?
-
Pavan almost 7 yearsDoes the
params[:answer]
only available when you submit the form? -
Pavan almost 7 yearsAlso can you update the question with the
params
that are generated in the server on the initial load? -
LarsH over 3 years@CiroSantilli郝海东冠状病六四事件法轮功 A byte string isn't a byte array. stackoverflow.com/questions/1740696/…
-
Ciro Santilli OurBigBook.com over 3 years@LarsH fair enough. @ recursive: date is not the main factor: meta.stackexchange.com/questions/147643/…
-
-
sath garcia over 15 yearsTwo ways to do it in 2.x, three ways in 3.x. So much for "there's only one way to do it"...
-
Crescent Fresh over 15 yearsOther two ways are more 'built-in' so I would actually use one of those.
-
Ishbir over 15 years@technomalogical: your comment is irrelevant to the answer; perhaps you should delete it and change it into a post to comp.lang.python .
-
nosklo over 15 years@technomalogical: I agree with ΤΖΩΤΖΙΟΥ. Also, you got it wrong. The correct phrase is: There should be one-- and preferably only one --obvious way to do it.
-
Scott Griffiths almost 13 yearsNote that in Python 3.2 (whether by design or a bug I'm not sure)
unhexlify
now won't accept a string, but only bytes. Pretty silly really, but it means you'd need to useb = unhexlify(bytes(myhexstr, 'utf-8'))
-
Abbafei almost 10 years
codecs.decode('0a0a0a', 'hex_codec')
should work for 2.x and 3.x :-) -
berto over 8 yearsAnd one additional step, I wanted a byte string (e.g. Python 3's b'\x04\xea[...]'), which you can get from a bytearray with
bytes(bytearray.fromhex('deadbeef'))
-
Martijn Pieters almost 8 years@berto: in that case there is a more direct route in the form of
binascii.unhexlify()
. -
berto almost 8 yearsThanks, @MartijnPieters, I'll give that a shot
-
Bash almost 4 yearsThis seem like the most direct way to do what the original post is asking. Is there a reason this isn't the accepted answer?
-
Klaws over 3 yearsThe fromhex() method (of both bytes and bytearray) will also work when the hex numbers are separated by spaces. Very convenient!
-
Mike Martin over 3 yearsThis really should be the accepted answer. The current accepted answer does not do what the question asked. It returns a mutable array of bytes, not a bytestring.
-
Mike Martin over 3 yearsThis answer does not do what the question asked. It returns a mutable array of bytes, not a python bytestring. That's like returning an array of strings rather than a string.
-
LarsH over 3 years@MartijnPieters Seems like
bytes.fromhex()
is also more direct, and a bit less obscure / more parsimonious. docs.python.org/3/library/stdtypes.html#bytes.fromhex -
Martijn Pieters over 3 years@LarsH: that method is not available in older Python 2 releases. That doesn't matter any more today, but it was an issue in 2016.
-
LarsH over 3 years@MartijnPieters I wondered if that was the case, but I didn't look far enough to find out.
-
B Bulfin over 2 years@MikeMartin I accepted this answer, only 12 years after it was posted.