文字列を設定された数の要素に短縮する推奨アルゴリズムはありますか (数値と文字列が混在している可能性があります)
澤さんのコメントによると、そのようなアルゴリズムはありません。
ただし、許可された文字列のセットが限られている場合は、それらを列挙して、その数を適切な基数で表すことができます。URL パス内の任意の圧縮データを表すのに理想的な Base 64 のよく知られており、十分にサポートされている「url セーフ」バージョンがあります。
たとえば、整数の注文 ID を取得するだけで、すでに列挙可能です。最大許容値が 32 ビット整数であると安全に想定できる場合は、次のようにエンコードできます。
require 'base64'
number_to_encode = 1_234_567_890
compact_string = [number_to_encode].pack('N*') # Network byte order
encoded = Base64.urlsafe_encode64( compact_string )
# => "SZYC0g=="
これは最大 10 桁の ID を取得し、そこから 8 文字の URL 文字列を作成します。必要な数にデコードするには:
require 'base64'
string_to_decode = "SZYC0g==" # e.g. params[:order_id] from /o/:order_id
packed_string = Base64.urlsafe_decode64( string_to_decode )
number = packed_string.unpack('N*').first
# => 1234567890
原則として、関連するコントローラーでデータを解凍して曖昧さをなくすことができれば、この方法であらゆる種類のデータを表現できます。ただし、圧縮には制限があります。任意の 32 ビット整数であるパラメーターを取り、それを 5 つの base64 文字に適合させることはできません (各 base64 文字はせいぜい 6 ビットのデータであるため)。
bit.ly や tinyurl.com で見たような短い URL が必要な場合は、可能な URL の大きなルックアップ テーブルを作成し、上記と同様の方法でそのテーブルの各行の ID をエンコードします。または、このデータを各モデルの一意のインデックスとして保存し、その列にシーケンス番号を入れるか、一意性をテストするランダムな文字列を生成することもできます。これらすべてのアプローチは本質的に、解決する参照の限定セットを持ち、それを数値 (項目の実際の数、または理論上の最大値を下回るように選択された固有のもの) に変換し、Base64 などのエンコード方式を使用して表現することに要約されます。 base 10 を使用していた場合よりも文字数が少なくなります。