1

私はコンピュータサイエンスの学生であり、コースの1つでBaseX(純粋なJava OSS XMLデータベース)を使用する必要があります。コードを閲覧しているときに、次のコードを発見しました。

  /**
    * Returns a md5 hash.
    * @param pw password string
    * @return hash
    */
   public static String md5(final String pw) {
     try {
       final MessageDigest md = MessageDigest.getInstance("MD5");
       md.update(Token.token(pw));
       final TokenBuilder tb = new TokenBuilder();
       for(final byte b : md.digest()) {
         final int h = b >> 4 & 0x0F;
         tb.add((byte) (h + (h > 9 ? 0x57 : 0x30)));
         final int l = b & 0x0F;
         tb.add((byte) (l + (l > 9 ? 0x57 : 0x30)));
       }
       return tb.toString();
     } catch(final Exception ex) {
       Main.notexpected(ex);
       return pw;
     }
   }

(ソース:https ://svn.uni-konstanz.de/dbis/basex/trunk/basex/src/main/java/org/basex/util/Token.java )

ただ興味がない:そこで何が起こっているのか?なぜこれらのバイトはMD5の後に動作するのですか?docstringは、MD5ハッシュを返すと言っています...そうですか?

4

3 に答える 3

4

使用されているクラスの定義を調べませんでしたが、バイト演算は返されたバイト配列を16進文字の文字列にエンコードしているようです。

for(final byte b : md.digest()) {
  // get high 4 bytes of current byte
  final int h = b >> 4 & 0x0F;
  // convert into hex digit (0x30 is '0' while 0x57+10 is 'a')
  tb.add((byte) (h + (h > 9 ? 0x57 : 0x30))); 
  // the same for the bottom 4 bits
  final int l = b & 0x0F;
  tb.add((byte) (l + (l > 9 ? 0x57 : 0x30)));
}

これは、マジックナンバーの使用が悪い理由の良い例です。私は、Pythonインタープリターでチェックせずに、0x57+10が「a」のASCII/Unicodeコードポイントであることを正直に思い出せませんでした。

于 2010-06-03T13:48:09.443 に答える
1

Mattiは正しいと思います-md.digest()がbyte []を返し、BaseXは文字列(したがってTokenBuilder)を優先してトークンを使用するためです。したがって、md.digest()からStringへの変換は、Digest-HexからTokenへの変換を介して行われます。

正確に読むのは簡単ではありませんが、ApacheCommonsがコーデックライブラリ でmd5ハッシュの文字列値を取得するために行うことと非常によく似ています。

于 2010-06-03T22:12:10.950 に答える
0

これは、マジックナンバーの使用が悪い理由の良い例です。

まあ、これは他の人によって変更されることを想定されていないコアメソッドです-そしてこれはそれを行うための最も効率的な方法のように見えます。しかし、確かに、ドキュメントの方が優れている可能性があります。コアメソッドについて話すと、Integer.getChars()のようなコードを見る価値があります。

http://www.docjar.com/html/api/java/lang/Integer.java.html

于 2010-06-04T11:28:11.797 に答える