0

これは、作業の修正なしの問題を解決するために私が引き受けたちょっとした副次的なプロジェクトです。私たちのシステムは、別のものの組み合わせを表すコードを出力します。いくつかのサンプルコードは次のとおりです。

9-9-0-4-4-5-4-0-2-0-0-0-2-0-0-0-0-0-2-1-2-1-2-2-2- 4

9-5-0-7-4-3-5-7-4-0-5-1-4-2-1-5-5-4-6-3-7-9-72

9-15-0-9-1-6-2-1-2-0-0-1-6-0-7

私がこれまでに見たスロットの1つの最大数は約150ですが、おそらくもっと高くなるでしょう。

システムが設計されたとき、このコードがどのように見えるかについての要件はありませんでした。しかし今、クライアントは一枚の紙から手でそれを入力できることを望んでいます。これは上記のコードには適していません。何もしないと言ったのですが、やりがいのある挑戦のようです。

私の質問は、このコードの損失のない圧縮を開始するのに適した場所はどこですか?このコードを短いキーで保存するなどの明らかな解決策はオプションではありません。私たちのデータベースは読み取り専用です。このコードをより人間に優しいものにするために、双方向のメソッドを構築する必要があります。

4

3 に答える 3

1

1) 間違いなくチェックサムが必要であることに同意します。十分に訓練されたスタッフと、自動クロスチェックを備えた独立した重複キーイングがない限り、データ入力エラーは非常に一般的です。

2) http://en.wikipedia.org/wiki/Huffman_codingを使用して、数値のリストをビットのストリームに変換することをお勧めします。これに必要な確率を取得するには、適切なサイズの実際のデータのサンプルが必要です。そのため、Ni をデータ内に数値 i が出現する回数に設定して、カウントを行うことができます。次に、確率を少し滑らかにする Pi = (Ni + 1) / (Sum_i (Ni + 1)) を設定することをお勧めします。また、この方法では、たとえば数字 0 ~ 150 が表示されている場合、数字 151 ~ 255 を入力して Ni = 0 に設定することで、少し余裕を持たせることができます。稀に大きな数字を回避する別の方法は、ある種のエスケープ シーケンスを追加することです。 .

3) 結果として得られる一連のビットを人々が入力する方法を見つけることは、実際には応用心理学の問題ですが、つまむべきアイデアのいくつかの提案を以下に示します。

3a) ソフトウェア ライセンス - 64 文字のアルファベットで 1 文字あたり 6 ビットをエンコードするだけですが、文字をグループ化して、人々が配置しやすいようにします (例: BC017-06777-14871-160C4)。

3b) 英国の車のナンバー プレート。アルファベットの変更を使用して、文字をグループ化する方法を人々に示します。例: ABCD0123EFGH4567IJKL...

3c) 本当に大きなアルファベット - 適切なサイズの n に対して 2^n 単語のリストを自分で取得し、n ビットを単語としてエンコードします (例: GREEN ENCHANTED LOGICIAN... -

于 2011-09-04T05:24:55.343 に答える
0

しばらく前にこの問題が心配でした。base64よりもはるかに優れた方法はありません。文字ごとにさらに数ビットを絞り込もうとしても、努力する価値はありません(「奇妙な」ビット数に入ると、エンコードとデコードがより複雑になります)。しかし同時に、入力時にエラーが発生する可能性が高いものになります(0とOなどを混同します)。1つのオプションは、変更された文字と文字のセットを選択することです(したがって、ベース64のままですが、たとえば、「0」の代わりに「>」を使用します。もう1つは、チェックサムを追加することです。実装を簡単にするために、チェックサムアプローチの方が優れていました。

残念ながら、これ以上進むことはありませんでした。方向が変わったため、コードや特定のチェックサムの選択肢を提供することはできません。

ps説明しなかったステップが欠落していることに気づきました。エンコードする前に、テキストをバイナリ形式に圧縮しようとしていました(標準の圧縮アルゴリズムを使用)。要約すると、圧縮、チェックサムの追加、base64エンコード。Base 64デコード、チェックサムの確認、解凍。

于 2011-09-03T23:59:32.020 に答える
0

これは、私が過去に使用したものと似ています。確かにもっと良い方法はありますが、当時の要件であった Transact-SQL へのミラーリングが簡単だったので、この方法を使用しました。ID の分布がランダムでない場合は、これを変更してハフマン エンコーディングを組み込むことができますが、おそらく不要です。

言語を指定しなかったので、これは c# ですが、どの言語にも簡単に移行できるはずです。ルックアップでは、よく混同される文字が省略されていることがわかります。これにより、エントリーが高速化されるはずです。長さを固定する必要もありましたが、これを変更するのは簡単です。

static public class CodeGenerator
{
    static Dictionary<int, char> _lookupTable = new Dictionary<int, char>();

    static CodeGenerator()
    {
        PrepLookupTable();
    }

    private static void PrepLookupTable()
    {
        _lookupTable.Add(0,'3');
        _lookupTable.Add(1,'2');
        _lookupTable.Add(2,'5');
        _lookupTable.Add(3,'4');
        _lookupTable.Add(4,'7');
        _lookupTable.Add(5,'6');
        _lookupTable.Add(6,'9');
        _lookupTable.Add(7,'8');
        _lookupTable.Add(8,'W');
        _lookupTable.Add(9,'Q');
        _lookupTable.Add(10,'E');
        _lookupTable.Add(11,'T');
        _lookupTable.Add(12,'R');
        _lookupTable.Add(13,'Y');
        _lookupTable.Add(14,'U');
        _lookupTable.Add(15,'A');
        _lookupTable.Add(16,'P');
        _lookupTable.Add(17,'D');
        _lookupTable.Add(18,'S');
        _lookupTable.Add(19,'G');
        _lookupTable.Add(20,'F');
        _lookupTable.Add(21,'J');
        _lookupTable.Add(22,'H');
        _lookupTable.Add(23,'K');
        _lookupTable.Add(24,'L');
        _lookupTable.Add(25,'Z');
        _lookupTable.Add(26,'X');
        _lookupTable.Add(27,'V');
        _lookupTable.Add(28,'C');
        _lookupTable.Add(29,'N');
        _lookupTable.Add(30,'B');          
    }


    public static bool TryPCodeDecrypt(string iPCode, out Int64 oDecryptedInt)
    {
        //Prep the result so we can exit without having to fiddle with it if we hit an error.
        oDecryptedInt = 0;

        if (iPCode.Length > 3)
        {
            Char[] Bits = iPCode.ToCharArray(0,iPCode.Length-2);

            int CheckInt7 = 0; 
            int CheckInt3 = 0;
            if (!int.TryParse(iPCode[iPCode.Length-1].ToString(),out CheckInt7) ||
                !int.TryParse(iPCode[iPCode.Length-2].ToString(),out CheckInt3))
            {
                //Unsuccessful -- the last check ints are not integers.
                return false;
            }
            //Adjust the CheckInts to the right values.
            CheckInt3 -= 2;
            CheckInt7 -= 2;

            int COffset = iPCode.LastIndexOf('M')+1;


            Int64 tempResult = 0;
            int cBPos = 0;
            while ((cBPos + COffset) < Bits.Length)
            {
                //Calculate the current position.
                int cNum = 0;
                foreach (int cKey in _lookupTable.Keys)
                {
                    if (_lookupTable[cKey] == Bits[cBPos + COffset])
                    {
                        cNum = cKey;
                    }
                }
                tempResult += cNum * (Int64)Math.Pow((double)31, (double)(Bits.Length - (cBPos + COffset + 1)));
                cBPos += 1;
            }

            if (tempResult % 7 == CheckInt7 && tempResult % 3 == CheckInt3)
            {
                 oDecryptedInt =  tempResult;
                return true;    
            }


            return false;

        }
        else
        {
            //Unsuccessful -- too short.
            return false;
        }
    }
    public static string PCodeEncrypt(int iIntToEncrypt, int iMinLength)
    {
        int Check7 = (iIntToEncrypt % 7) + 2;
        int Check3 = (iIntToEncrypt % 3) + 2;

        StringBuilder result = new StringBuilder();
        result.Insert(0, Check7);
        result.Insert(0, Check3);

        int workingNum = iIntToEncrypt;

        while (workingNum > 0)
        {
            result.Insert(0, _lookupTable[workingNum % 31]);
            workingNum /= 31;
        }

        if (result.Length < iMinLength)
        {
            for (int i = result.Length + 1; i <= iMinLength; i++)
            {
                result.Insert(0, 'M');
            }
        }

        return result.ToString();
    }

}
于 2011-09-06T04:22:22.553 に答える