在 Python 中将 int 转换为 ASCII 并返回

我正在为我的网站制作一个 URL 缩短程序,我目前的计划(我愿意接受建议)是使用一个节点 ID 来生成缩短的 URL。因此,在理论上,节点26可能是 short.com/z,节点1可能是 short.com/a,节点52可能是 short.com/Z,节点104可能是 short.com/ZZ。当用户访问该 URL 时,我需要逆转这个过程(显然)。

我可以想出一些笨拙的方法来解决这个问题,但我猜还有更好的方法。有什么建议吗?

431899 次浏览

使用 hex(id)[2:]int(urlpart, 16)。还有别的选择。Base32编码您的 id 也可以工作,但是我不知道有没有内置在 Python 中的 base32编码库。

显然,在 Python 2.4中使用 Base64模块引入了 base32编码器。您可以尝试使用 b32encodeb32decode。你应该给 Truecasefoldmap01选项的 b32decode的情况下,人们写下你缩短的网址。

事实上,我收回刚才的话。我仍然认为 base32编码是一个好主意,但是这个模块对于 URL 缩短来说没有用处。您可以查看模块中的实现,并针对这个特定情况制作自己的实现。:-)

ASCII 到 int:

ord('a')

给出 97

回到一个字符串:

  • 在 Python 2: str(unichr(97))
  • 在 Python 3: chr(97)

给出 'a'

BASE58编码 URL 怎么样? 就像 flickr 一样。

# note the missing lowercase L and the zero etc.
BASE58 = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ'
url = ''
while node_id >= 58:
div, mod = divmod(node_id, 58)
url = BASE58[mod] + url
node_id = int(div)


return 'http://short.com/%s' % BASE58[node_id] + url

把它变回一个数字也不是什么大事。

>>> ord("a")
97
>>> chr(97)
'a'

如果多个字符绑定在一个整数/长度内,我的问题是:

s = '0123456789'
nchars = len(s)
# string to int or long. Type depends on nchars
x = sum(ord(s[byte])<<8*(nchars-byte-1) for byte in range(nchars))
# int or long to string
''.join(chr((x>>8*(nchars-byte-1))&0xFF) for byte in range(nchars))

产生 '0123456789'x = 227581098929683594426425L

显然我来晚了,只是想分享一个我经常用的片段。

/**
* 62 = 26 + 26 +10
*
* @param id
* @return
*/
public String base62(long id) {
StringBuilder sb = new StringBuilder();
while (id >= 62) {
int remainer = (int) (id % 62);
id = id / 62;
sb.append(index2char(remainer));
}
sb.append(index2char(id));


return sb.reverse().toString();
}


public long reverseBase62(String s) {
long r = 0;
for (int i = 0; i < s.length(); i++) {
r = r * 62;
int index = char2index(s.charAt(i));
if (index == -1) {
throw new IllegalArgumentException(
String.format("[%s] is in malformation, should only contain 0~9, a~z, A~Z", s));
}
r += index;
}


return r;
}
private char index2char(long index) {
if (index < 10) {
return (char) ('0' + index);
}
if (index < 36) {
return (char) ('a' + index - 10);
}
return (char) ('A' + index - 36);
}






private int char2index(char c) {
if ('0' <= c && c <= '9') {
return c - '0';
}
if ('a' <= c && c <= 'z') {
return c - 'a' + 10;
}
if ('A' <= c && c <= 'Z') {
return c - 'A' + 36;
}
return -1;
}