问题
In PHP, given a string value (integers separated by chars), we can calculate its integer representation:
$hashable = "123A123"; // notice "A" delim
$hash_int = base_convert($hashable, 11, 10);
echo $hash_int;
Output
2151042
It's useful because result is unique for huge range of strings (short ones, of course). I use it for ID generation in my application.
How can we do same conversions in python? Is it possible to generate equal integers for same strings in both PHP and python?
Maybe first we need to take hash int of hashable string and then convert the base of integer but how exactly we do this?
回答1:
Previously suggested method will fail for binary and many other conversions, this will go from any base from 2 to 36 and return 0 for invalid strings as per the php implementation, the php implementation does not ignore letters in the output unless you give invalid input for the base and then it tries to find just the digits and convert so you also cannot return an int as you can and will get letters in the output:
def to_base(n, bse):
digs = "0123456789abcdefghijklmnopqrstuvwxyz"
tmp = []
while n:
n, i = divmod(n, bse)
tmp.append(digs[i])
return "".join(tmp[::-1])
def chng_frm_base(s, frm_bse, to_bse):
if to_bse < 2 or to_bse > 36 or frm_bse < 2 or frm_bse > 36:
raise ValueError("bases must be between 2-36")
try:
return to_base(int(s, frm_bse), to_bse)
except ValueError:
try:
n = int("".join([ch for ch in s if ch.isdigit()]),frm_bse)
return to_base(n, to_bse)
except ValueError:
return 0
Output:
In [13]: chng_frm_base("123A123", 11, 10)
Out[13]: '2151042'
In [14]: chng_frm_base("123A123", 11, 8)
Out[14]: '10151202'
In [15]: chng_frm_base("123A123", 11, 2)
Out[15]: '1000001101001010000010'
In [16]: chng_frm_base("123A123", 11, 35)
Out[16]: '1f5xc'
In [17]: chng_frm_base("123A123", 11, 1)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-17-9776e0abca26> in <module>()
----> 1 chng_frm_base("123A123", 11, 1)
<ipython-input-2-9c00d800545d> in chng_frm_base(s, frm_bse, to_bse)
10 def chng_frm_base(s, frm_bse, to_bse):
11 if to_bse < 2 or to_bse > 36 or frm_bse < 2 or frm_bse > 36:
---> 12 raise ValueError("bases must be between 2-36")
13 try:
14 return (to_base(int(s, frm_bse), to_bse))
ValueError: bases must be between 2-36
In [18]: chng_frm_base("hello world!", 10, 2)
Out[18]: 0
Which if you run the same examples using php outputs the same values for all.
来源:https://stackoverflow.com/questions/33792694/base-convert-in-python-given-a-string