I'm given a hexadecimal number in string form with a leading "0x" that may contain 1-8 digits, but I need to pad the number with zeros so that it always has 8 digits (10 characters including the "0x").

For example:

• "0x123" should become "0x00000123".
• "0xABCD12" should become "0x00ABCD12".
• "0x12345678" should be unchanged.

I am guaranteed to never see more than 8 digits, so this case does not need to be handled.

Right now, I have this coded as:

padded = '0x' + '0' * (10 - len(mystring)) + mystring[2:]


It works, but feels ugly and unpythonic. Any suggestions for a cleaner method?

Perhaps you're looking for the .zfill method on strings. From the docs:

Help on built-in function zfill:

zfill(...)
S.zfill(width) -> string

Pad a numeric string S with zeros on the left, to fill a field
of the specified width.  The string S is never truncated.


Your code can be written as:

def padhexa(s):
return '0x' + s[2:].zfill(8)


• This is exactly what I was looking for. Thanks! – Sohcahtoa82 Oct 23 '14 at 17:42

I would suggest interpreting the input as a number, then using standard number-formatting routines.

padded = str.format('0x{:08X}', int(mystring, 16))


The string → int → string round trip may seem silly, but it is also beneficial in that it provides validation of the input string.

I'd use something like this:

def format_word(word, prefix=None, size=None):
if prefix is None:
prefix = '0x'
if size is None:
size = 2
if not isinstance(word, int):
word = int(word, 16)
if word > 2**(8 * size) - 1:
raise ValueError('word too great')
prefix=prefix,
word=word,


Using None as defaults and assigning true defaults later makes it easier to wrap the function.

def format_word(word, prefix=None, size=None):
if prefix is None:
prefix = '0x'
if size is None:
size = 2


If word isn't already a int try to convert it. It'll choke if it's not a str, bytes, or bytearray. We need the type check because int(word, 16) would choke if word was already an int.

if not isinstance(word, int):
word = int(word, 16)


Check that the word isn't going break the formatting.

if word > 2**(8 * size) - 1:
raise ValueError('word too great')


Finally, format the word, using keywords to decouple the string to the argument order.

return '{prefix}{word:0{padding}X}'.format(
prefix=prefix,
word=word,
`