1日あたり1000を超えるが10000未満の新しいレコードを処理する必要がある
GUID / UUID、自動インクリメント番号などは使用できません。
理想的には5または6文字の長さである必要があり、もちろんアルファにすることもできます
可能であれば、既存のよく知られたアルゴを再利用したい
何かありますか?
1日あたり1000を超えるが10000未満の新しいレコードを処理する必要がある
GUID / UUID、自動インクリメント番号などは使用できません。
理想的には5または6文字の長さである必要があり、もちろんアルファにすることもできます
可能であれば、既存のよく知られたアルゴを再利用したい
何かありますか?
回答:
ベース62は、省略されたURLのtinyurlおよびbit.lyによって使用されます。これは、「一意の」人間が読めるIDを作成するためのよく理解されている方法です。もちろん、作成されたIDを保存し、作成時に重複をチェックして一意性を確保する必要があります。(回答の下部にあるコードを参照してください)
ベース62の一意性メトリック
六十二進法の5文字は62 ^ 5の一意のIDを提供します= 916,132,832(〜10億)1日あたり10,000 IDで、91k +日は問題ありません
六十二進法の6文字は62 ^ 6の一意のIDを提供します= 56,800,235,584(560億以上)1日あたり10,000 IDで、500万日以上問題ありません
ベース36の一意性メトリック
6文字で36 ^ 6の一意のIDが得られます= 2,176,782,336(2+億)
7文字で36 ^ 7の一意のID = 78,364,164,096(780億以上)
コード:
public void TestRandomIdGenerator()
{
// create five IDs of six, base 62 characters
for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase62(6));
// create five IDs of eight base 36 characters
for (int i=0; i<5; i++) Console.WriteLine(RandomIdGenerator.GetBase36(8));
}
public static class RandomIdGenerator
{
private static char[] _base62chars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
.ToCharArray();
private static Random _random = new Random();
public static string GetBase62(int length)
{
var sb = new StringBuilder(length);
for (int i=0; i<length; i++)
sb.Append(_base62chars[_random.Next(62)]);
return sb.ToString();
}
public static string GetBase36(int length)
{
var sb = new StringBuilder(length);
for (int i=0; i<length; i++)
sb.Append(_base62chars[_random.Next(36)]);
return sb.ToString();
}
}
出力:
z5KyMg wd4SUp uSzQtH UPrGAT UIf2IS QCF9GNM5 0UV3TFSS 3MG91VKP 7NTRF10T AJK3AJU7
任意の数値(DB IDなど)を文字列(saltを使用)に変換するhttp://hashids.org/をお勧めします。
これにより、この文字列をデコードして数値に戻すことができます。したがって、データベースに保存する必要はありません。
JavaScript、Ruby、Python、Java、Scala、PHP、Perl、Swift、Clojure、Objective-C、C、C ++ 11、Go、Erlang、Lua、Elixir、ColdFusion、Groovy、Kotlin、Nim、VBA、 CoffeeScriptおよびNode.jsおよび.NET用。
OPと同様の要件がありました。私は利用可能なライブラリを調べましたが、それらのほとんどはランダム性に基づいており、私はそれを望んでいませんでした。ランダムに基づいておらず、まだ非常に短いものは実際には見つかりませんでした...そこで、Flickrが使用する手法に基づいて自分でローリングすることになりましたが、調整が少なくて済み、オフラインでの期間を長くできるように変更されました。
要するに:
短所:
利点
クライアント側のJavascriptライブラリとJavaEEサーバーの実装の両方を公開しました。他の言語でのサーバーの実装も簡単なはずです。
プロジェクトは次のとおりです。
suid-分散サービス-短くて甘いユニークなID
suid-server-java -JavaEEテクノロジースタックのSuidサーバー実装。
どちらのライブラリも、リベラルなクリエイティブコモンズオープンソースライセンスの下で利用できます。これが、他の誰かが短い一意のIDを探すのに役立つことを願っています。
suid
か?
数年前に開発していたアプリケーションでこの問題を解決したとき、ベース36を使用しました。人間が読める形式の適度に一意の番号を生成する必要がありました(とにかく現在の暦年内)。今年の1月1日の深夜からのミリ秒単位の時間を使用して(毎年、タイムスタンプが重複する可能性があるため)、それをベース36の数値に変換することを選択しました。開発中のシステムで致命的な問題が発生した場合、ベース36の番号(7文字)が生成され、Webインターフェイスを介してエンドユーザーに表示され、発生した問題(および番号)をテクニカルサポート担当者(担当者)に中継できます。次に、それを使用して、スタックトレースが開始されたログ内のポイントを見つけることができます)。のような数56af42g7の2016-01-21T15:34:29.933-08:00のようなタイムスタンプや5f0d3e0c-da96-11e5-b5d2-0a1d41d68578のようなランダムなUUIDよりも、ユーザーが読み取りと中継を行うのは非常に簡単です。
Base64形式を使用してGUIDをエンコードし、末尾の==を切り捨てて22文字の文字列を取得するという単純さが本当に気に入っています(1行のコードが必要で、いつでもGUIDに戻すことができます)。残念ながら、+文字と/文字が含まれることがあります。データベースには問題ありませんが、URLには適していませんが、他の回答を評価するのに役立ちました:-)
Christiaan vanBergenによるhttps://www.codeproject.com/Tips/1236704/Reducing-the-string-Length-of-a-Guidから
Base64を使用してGuid(16バイト)をASCII表現に変換すると、22文字の使用可能で一意のmessageIDが生成されることがわかりました。
var newGuid = Guid.NewGuid();
var messageID = Convert.ToBase64String(newGuid.ToByteArray());
var message22chars = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Substring(0,22);
例:Guid'e6248889-2a12-405a-b06d-9695b82c0a9c '(文字列の長さ:36)はBase64表現を取得します:' iYgk5hIqWkCwbZaVuCwKnA == '(文字列の長さ:24)
Base64表現は「==」文字で終わります。一意性に影響を与えることなく、これらを切り捨てることができます。長さがわずか22文字の識別子を残します。