This is not meant to be an answer, but rather an explanation of the previous one. If any of this makes sense, please upvote user3179904's answer instead.
His answer was:
'0'*(len(si:=f'{i:x}')%2)+si
Let's take this apart, like Jack the Reaper. For the following sections, I'll be using the integer value 4151900041497450638097112925
. I'll also be showing code and results from the Python CLI.
This is done by the central bit:
f'{i:x}'
In here, the variable i
is the victim, meaning it carries the integer value you wish to convert into a well padded hexadecimal. So, for now we have:
>>> i = 4151900041497450638097112925
>>> f'{i:x}'
'd6a5f083f285c3e5195df5d'
>>> len(f'{i:x}')
23
As you see, easy, but the length is odd.
:=
) operatorNow we grab a bit more of code:
>>> si:=f'{i:x}'
File "<console>", line 1
si:=f'{i:x}'
^^
SyntaxError: invalid syntax
>>> (si:=f'{i:x}')
'd6a5f083f285c3e5195df5d'
>>> si
'd6a5f083f285c3e5195df5d'
That was not a mistake. That was to show that:
si
still exists outside / after the expression, unlike, for instance, variables inside a comprehension.The next section answers the question above:
len(si:=f'{i:x}')%2
First, it gets the total length:
>>> len(si:=f'{i:x}')
23
and then it gets the division by two remainder:
>>> len(si:=f'{i:x}')%2
1
>>> 23%2
1
Of course, if this is the number of zeros you need, let's give you just that:
>>> '0'*len(si:=f'{i:x}')%2
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: not all arguments converted during string formatting
>>> '0'*(len(si:=f'{i:x}')%2)
'0'
Again, not a mistake but just to highlight that those parenthesis are required, otherwise it would first multiply '0'
by 23 and then find the remainder of that, which is a string.
NOTE: the number of zeros needed will always be none or one. I know this is already abundantly obvious, but just in case...
si
bit? Right.>>> '0'*(len(si:=f'{i:x}')%2)
'0'
>>> si
'd6a5f083f285c3e5195df5d'
>>> '0'*(len(si:=f'{i:x}')%2)+si
'0d6a5f083f285c3e5195df5d'
>>> len('0'*(len(si:=f'{i:x}')%2)+si)
24
And there you have it: an even-lengthed hex
representation of your int
.
That's an easy one! The number I used as an example was the serial number of a digital certificate (now expired, so hold your horses). It so happens that openssl
, the tool to check these, exposes the serial number as a colon-separated sequence of bytes, in this case:
Serial Number:
0d:6a:5f:08:3f:28:5c:3e:51:95:df:5d
The usual way to go about this would be to split that final string by grops of 2 chars and then join these with a colon. It so happens that if you try that on 'd6a5f083f285c3e5195df5d'
, you end up with:
'd6:a5:f0:83:f2:85:c3:e5:19:5d:f5:d'
which is both different from the representation from openssl (and thus not immediately comparable) and overall weird in terms of byte boundaries.
Of course, applying all the magic of the previous answer, what you end up with is:
'0d:6a:5f:08:3f:28:5c:3e:51:95:df:5d'
which is just what the doctor ordered.