Python で一意の URL をhttp://imgur.com/gM19gまたはhttp://tumblr.com/xzh3bi25y にする方法 URL をもっと短くしたい。
12 に答える
編集:ここで、私はあなたのためにモジュールを書きました。これを使って。http://code.activestate.com/recipes/576918/
1 からカウントアップすると、短くて一意の URL が保証されます。/1、/2、/3 ... など
アルファベットに大文字と小文字を追加すると、質問のような URL が得られます。また、base-10 ではなく base-62 でカウントしているだけです。
唯一の問題は、URL が連続して来ることです。それを修正するには、この質問に対する私の回答をここで読んでください。
増加する整数範囲を最大 6 桁の基数 26 にマップしますが、予測できません
基本的なアプローチは、決定論を維持し、衝突がないことを保証しながら、増加する値のビットを単純に交換してランダム性の外観を与えることです。
ほとんどの URL 短縮サービスがランダムな文字列を使用しているかどうかはわかりません。私の印象では、URL をデータベースに書き込み、新しいレコードの整数 ID を短い URL として使用し、base 36 または 62 (文字 + 数字) でエンコードされています。
int を任意の基数の文字列に変換する Python コードはhereです。
このモジュールは、文字列がグローバルに一意であること (UUID) を保証して、あなたが望むことを行います:
http://pypi.python.org/pypi/shortuuid/0.1
より短いものが必要な場合は、目的の長さに切り捨てても、衝突を合理的に回避できるものを取得できるはずです。
この回答はかなり遅れていますが、URL 短縮プロジェクトの作成を計画していたときに、この質問に出くわしました. 完全に機能する URL 短縮機能 (ソース コードはamitt001/pygmy ) を実装したので、他の人のためにここに回答を追加します。
URL 短縮サービスの背後にある基本原則は、長い URL から int を取得し、base62 (base32 など) エンコーディングを使用して、この int を読みやすい短い URL に変換することです。
この int はどのように生成されますか?
ほとんどの URL 短縮サービスは、自動インクリメント データストアを使用して URL をデータストアに追加し、自動インクリメント ID を使用して int の base62 エンコーディングを取得します。
文字列プログラムからの base62 エンコードのサンプル:
# Base-62 hash
import string
import time
_BASE = 62
class HashDigest:
"""Base base 62 hash library."""
def __init__(self):
self.base = string.ascii_letters + string.digits
self.short_str = ''
def encode(self, j):
"""Returns the repeated div mod of the number.
:param j: int
:return: list
"""
if j == 0:
return [j]
r = []
dividend = j
while dividend > 0:
dividend, remainder = divmod(dividend, _BASE)
r.append(remainder)
r = list(reversed(r))
return r
def shorten(self, i):
"""
:param i:
:return: str
"""
self.short_str = ""
encoded_list = self.encode(i)
for val in encoded_list:
self.short_str += self.base[val]
return self.short_str
これは base62 エンコーディングを示す部分的なコードです。core/hashdigest.pyで完全な base62 エンコード/デコード コードを確認してください。
この回答のすべてのリンクは、私が作成したプロジェクトから短縮されています
UUID が長い理由は、グローバルに一意であることを保証できるように多くの情報が含まれているためです。
より短いものが必要な場合は、ランダムな文字列を生成し、それが既に生成された文字列の宇宙にあるかどうかを確認し、未使用の文字列が得られるまで繰り返す必要があります。ここでは同時実行性にも注意する必要があります (文字列のセットに挿入する前に、別のプロセスによって同じ文字列が生成された場合はどうなるでしょうか?)。
Python でランダムな文字列を生成するのに助けが必要な場合は、この別の質問が役立つかもしれません。
これを使用できるかどうかはわかりませんが、Zope でコンテンツ オブジェクトを生成し、現在の時刻文字列 (ミリ秒単位) に基づいて一意の数値 ID (例: 1254298969501) を取得します。
多分あなたは残りを推測することができます。ここで説明されているレシピを使用する: How to convert an integer to the shortest url-safe string in Python? 、ストレージを必要とせずに、実際のIDをオンザフライでエンコードおよびデコードします。たとえば、13 桁の整数は、base 62 では 7 文字の英数字に縮小されます。
実装を完了するために、「見つからない」URL をデコードして 301 リダイレクトを実行する短い (xxx.yy) ドメイン名を登録しました。
最初からやり直す場合は、エンコードの前に数値 ID から「最初からやり直す」時間 (ミリ秒単位) を減算し、デコード時に再度追加します。または、オブジェクトを生成するとき。なんでもいい。それははるかに短いでしょう..
これが Python であることは問題ではありませんが、必要な長さに対応するハッシュ関数が必要なだけです。たとえば、MD5 を使用して、最初のn
文字だけを取得します。ただし、その場合は衝突に注意する必要があるため、衝突検出に関してもう少し堅牢なものを選択することをお勧めします (素数を使用してハッシュ文字列の空間を循環させるなど)。
これを試してみてください http://code.google.com/p/tiny4py/ ... まだ開発中ですが、非常に便利です!!