If you have a maximum length for your input sprintf may help: sprintf "%016s", EXPR. It will align all your inputs to your max size, although you could still remove the leading \0s. (And I'm assuming you do want a byte string as the output, otherwise hex might help)
requires you to actually have a variable declared
You could use either
map or
for to alias the value of your EXPR to $_:
print unpack "H*", pack("H*", map { "0" x (length($_) % 2) . $_ } "a12
+");
print unpack "H*", pack("H*", "0" x (length($_) % 2) . $_ ) for "a12";
That's still not pretty (and you could do even worse, with an anonymous sub).
I don't get the issue with your helper function and circular packages though. Can't you just put the fonction alone in a file, in the worst case? Or, if it really comes to it, just redefine it wherever you need, the function is fairly short anyway:
sub zpad { my ($str,) = @_; length($str)%2 ? "0$str" : $str }
print unpack 'H*', pack 'H*', zpad "a30"