VBScript で MD5 を実装する (unibon)

2002年02月24日: 新規作成。
VBScript で MD5 を実装します。MD5 とは一方向ハッシュ関数です。
このページでは単に MD5 用のサブルーチンを紹介しますが、このサブルーチンを使った応用例としては、
パスワード管理に MD5 を使う
パスワード伝送に MD5 を使う
があります。

VB(Visual Basic) でも動作します。さらにオマケとして JavaScript で実装したサブルーチンも掲載します。サーバサイドとクライアントサイドの両方で使えると、なにかと応用がきいて便利でしょう。


VBScript 版

動作させるためには別途 ビットシフトのサブルーチン が必要です。
' このプログラムコードは RFC 1321 (The MD5 Message-Digest Algorithm) の参照インプリメンテーションを
' unibon が VBScript および VB(Visual Basic) に移植したものです。
' 権利については RFC 1321 中の記述が優先されます。
' This program code is "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm".

Option Explicit

' ここに、左シフト関数 sl, 右シフト関数 sr, 加算関数 add を挿入してください。
' http://www.geocities.co.jp/SiliconValley/4334/unibon/asp/bitshift2.html

Function ba(ByVal s) ' 文字列を文字の配列に変換する。
    Dim r
    If Len(s) = 0 Then ' 要素数が 0 個の配列のみ特別扱いする。
        r = Array()
    Else
        ReDim a(Len(s) - 1)
        Dim i
        For i = 0 To Len(s) - 1
            a(i) = Asc(Mid(s, i + 1, 1))
        Next
        r = a
    End If
    ba = r
End Function

Function FX(ByVal x, ByVal y, ByVal z)
    FX = (x And y) Or ((Not x) And z)
End Function

Function GX(ByVal x, ByVal y, ByVal z)
    GX = (x And z) Or (y And (Not z))
End Function

Function HX(ByVal x, ByVal y, ByVal z)
    HX = x Xor y Xor z
End Function

Function IX(ByVal x, ByVal y, ByVal z)
    IX = y Xor (x Or (Not z))
End Function

Function ROTATE_LEFT(ByVal x, ByVal n)
    ROTATE_LEFT = sl(x, n) Or sr(x, 32 - n)
End Function

Sub FF(ByRef a, ByVal b, ByVal c, ByVal d, ByVal x, ByVal s, ByVal ac)
    a = add(add(add(a, FX(b, c, d)), x), ac)
    a = ROTATE_LEFT(a, s)
    a = add(a, b)
End Sub

Sub GG(ByRef a, ByVal b, ByVal c, ByVal d, ByVal x, ByVal s, ByVal ac)
    a = add(add(add(a, GX(b, c, d)), x), ac)
    a = ROTATE_LEFT(a, s)
    a = add(a, b)
End Sub

Sub HH(ByRef a, ByVal b, ByVal c, ByVal d, ByVal x, ByVal s, ByVal ac)
    a = add(add(add(a, HX(b, c, d)), x), ac)
    a = ROTATE_LEFT(a, s)
    a = add(a, b)
End Sub

Sub II(ByRef a, ByVal b, ByVal c, ByVal d, ByVal x, ByVal s, ByVal ac)
    a = add(add(add(a, IX(b, c, d)), x), ac)
    a = ROTATE_LEFT(a, s)
    a = add(a, b)
End Sub

Sub MD5Init(ByRef state, ByRef count, ByRef buffer)
    count(0) = 0
    count(1) = 0
    
    state(0) = &H67452301
    state(1) = &HEFCDAB89
    state(2) = &H98BADCFE
    state(3) = &H10325476
End Sub

Sub MD5Update(ByRef state, ByRef count, ByRef buffer, ByRef inputx, ByVal inputLen)
    Dim i
    Dim index
    Dim partLen

    index = sr(count(0), 3) And &H3F
    
    count(0) = add(count(0), sl(inputLen, 3))
    If count(0) < sl(inputLen, 3) Then
        count(1) = add(count(1), 1)
    End If

    count(1) = add(count(1), sr(inputLen, 29))

    partLen = 64 - index

    If inputLen >= partLen Then
        Call MD5_memcpy(buffer, index, inputx, 0, partLen)
        Call MD5Transform(state, buffer, 0)

        For i = partLen To inputLen - 63 - 1 Step 64
            Call MD5Transform(state, inputx, i)
        Next
        index = 0
    Else
        i = 0
    End If

    Call MD5_memcpy(buffer, index, inputx, i, inputLen - i)
End Sub

Sub MD5Final(ByRef digest, ByRef state, ByRef count, ByRef buffer)
    Dim bits(7)
    Dim index
    Dim padLen

    Call Encode(bits, count, 8)

    index = sr(count(0), 3) And &H3F
    If index < 56 Then
        padLen = 56 - index
    Else
        padLen = 120 - index
    End If
    
    Dim PADDING
    PADDING = Array( _
        &H80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 _
    )
    Call MD5Update(state, count, buffer, PADDING, padLen)

    Call MD5Update(state, count, buffer, bits, 8)

    Call Encode(digest, state, 16)
    
    Dim i
    For i = 0 To UBound(state)
        state(i) = 0
    Next
    For i = 0 To UBound(count)
        count(i) = 0
    Next
    For i = 0 To UBound(buffer)
        buffer(i) = 0
    Next
End Sub

Sub MD5Transform(ByRef state, ByRef block, ByVal offset)
    Dim a
    a = state(0)
    Dim b
    b = state(1)
    Dim c
    c = state(2)
    Dim d
    d = state(3)
    
    Dim x(15)
    Call Decode(x, block, offset, 64)

    ' Round 1
    Call FF(a, b, c, d, x( 0),  7, &HD76AA478) '  1 S11
    Call FF(d, a, b, c, x( 1), 12, &HE8C7B756) '  2 S12
    Call FF(c, d, a, b, x( 2), 17, &H242070DB) '  3 S13
    Call FF(b, c, d, a, x( 3), 22, &HC1BDCEEE) '  4 S14
    Call FF(a, b, c, d, x( 4),  7, &HF57C0FAF) '  5 S11
    Call FF(d, a, b, c, x( 5), 12, &H4787C62A) '  6 S12
    Call FF(c, d, a, b, x( 6), 17, &HA8304613) '  7 S13
    Call FF(b, c, d, a, x( 7), 22, &HFD469501) '  8 S14
    Call FF(a, b, c, d, x( 8),  7, &H698098D8) '  9 S11
    Call FF(d, a, b, c, x( 9), 12, &H8B44F7AF) ' 10 S12
    Call FF(c, d, a, b, x(10), 17, &HFFFF5BB1) ' 11 S13
    Call FF(b, c, d, a, x(11), 22, &H895CD7BE) ' 12 S14
    Call FF(a, b, c, d, x(12),  7, &H6B901122) ' 13 S11
    Call FF(d, a, b, c, x(13), 12, &HFD987193) ' 14 S12
    Call FF(c, d, a, b, x(14), 17, &HA679438E) ' 15 S13
    Call FF(b, c, d, a, x(15), 22, &H49B40821) ' 16 S14

    ' Round 2
    Call GG(a, b, c, d, x( 1),  5, &HF61E2562) ' 17 S21
    Call GG(d, a, b, c, x( 6),  9, &HC040B340) ' 18 S22
    Call GG(c, d, a, b, x(11), 14, &H265E5A51) ' 19 S23
    Call GG(b, c, d, a, x( 0), 20, &HE9B6C7AA) ' 20 S24
    Call GG(a, b, c, d, x( 5),  5, &HD62F105D) ' 21 S21
    Call GG(d, a, b, c, x(10),  9,  &H2441453) ' 22 S22
    Call GG(c, d, a, b, x(15), 14, &HD8A1E681) ' 23 S23
    Call GG(b, c, d, a, x( 4), 20, &HE7D3FBC8) ' 24 S24
    Call GG(a, b, c, d, x( 9),  5, &H21E1CDE6) ' 25 S21
    Call GG(d, a, b, c, x(14),  9, &HC33707D6) ' 26 S22
    Call GG(c, d, a, b, x( 3), 14, &HF4D50D87) ' 27 S23
    Call GG(b, c, d, a, x( 8), 20, &H455A14ED) ' 28 S24
    Call GG(a, b, c, d, x(13),  5, &HA9E3E905) ' 29 S21
    Call GG(d, a, b, c, x( 2),  9, &HFCEFA3F8) ' 30 S22
    Call GG(c, d, a, b, x( 7), 14, &H676F02D9) ' 31 S23
    Call GG(b, c, d, a, x(12), 20, &H8D2A4C8A) ' 32 S24

    ' Round 3
    Call HH(a, b, c, d, x( 5),  4, &HFFFA3942) ' 33 S31
    Call HH(d, a, b, c, x( 8), 11, &H8771F681) ' 34 S32
    Call HH(c, d, a, b, x(11), 16, &H6D9D6122) ' 35 S33
    Call HH(b, c, d, a, x(14), 23, &HFDE5380C) ' 36 S34
    Call HH(a, b, c, d, x( 1),  4, &HA4BEEA44) ' 37 S31
    Call HH(d, a, b, c, x( 4), 11, &H4BDECFA9) ' 38 S32
    Call HH(c, d, a, b, x( 7), 16, &HF6BB4B60) ' 39 S33
    Call HH(b, c, d, a, x(10), 23, &HBEBFBC70) ' 40 S34
    Call HH(a, b, c, d, x(13),  4, &H289B7EC6) ' 41 S31
    Call HH(d, a, b, c, x( 0), 11, &HEAA127FA) ' 42 S32
    Call HH(c, d, a, b, x( 3), 16, &HD4EF3085) ' 43 S33
    Call HH(b, c, d, a, x( 6), 23,  &H4881D05) ' 44 S34
    Call HH(a, b, c, d, x( 9),  4, &HD9D4D039) ' 45 S31
    Call HH(d, a, b, c, x(12), 11, &HE6DB99E5) ' 46 S32
    Call HH(c, d, a, b, x(15), 16, &H1FA27CF8) ' 47 S33
    Call HH(b, c, d, a, x( 2), 23, &HC4AC5665) ' 48 S34

    ' Round 4
    Call II(a, b, c, d, x( 0),  6, &HF4292244) ' 49 S41
    Call II(d, a, b, c, x( 7), 10, &H432AFF97) ' 50 S42
    Call II(c, d, a, b, x(14), 15, &HAB9423A7) ' 51 S43
    Call II(b, c, d, a, x( 5), 21, &HFC93A039) ' 52 S44
    Call II(a, b, c, d, x(12),  6, &H655B59C3) ' 53 S41
    Call II(d, a, b, c, x( 3), 10, &H8F0CCC92) ' 54 S42
    Call II(c, d, a, b, x(10), 15, &HFFEFF47D) ' 55 S43
    Call II(b, c, d, a, x( 1), 21, &H85845DD1) ' 56 S44
    Call II(a, b, c, d, x( 8),  6, &H6FA87E4F) ' 57 S41
    Call II(d, a, b, c, x(15), 10, &HFE2CE6E0) ' 58 S42
    Call II(c, d, a, b, x( 6), 15, &HA3014314) ' 59 S43
    Call II(b, c, d, a, x(13), 21, &H4E0811A1) ' 60 S44
    Call II(a, b, c, d, x( 4),  6, &HF7537E82) ' 61 S41
    Call II(d, a, b, c, x(11), 10, &HBD3AF235) ' 62 S42
    Call II(c, d, a, b, x( 2), 15, &H2AD7D2BB) ' 63 S43
    Call II(b, c, d, a, x( 9), 21, &HEB86D391) ' 64 S44

    state(0) = add(state(0), a)
    state(1) = add(state(1), b)
    state(2) = add(state(2), c)
    state(3) = add(state(3), d)

    Dim i
    For i = 0 To UBound(x)
        x(i) = 0
    Next
End Sub

Sub Encode(ByRef output, ByRef inputx, ByVal lenx)
    Dim i
    i = 0
    Dim j
    j = 0
    Do While j < lenx
        output(j) = inputx(i) And &HFF
        output(j + 1) = sr(inputx(i), 8) And &HFF
        output(j + 2) = sr(inputx(i), 16) And &HFF
        output(j + 3) = sr(inputx(i), 24) And &HFF
        i = i + 1
        j = j + 4
    Loop
End Sub

Sub Decode(ByRef output, ByRef inputx, ByVal inputxOffset, ByVal lenx)
    Dim i
    i = 0
    Dim j
    j = 0
    Do While j < lenx
        Dim k
        k = j + inputxOffset
        output(i) = inputx(k) Or sl(inputx(k + 1), 8) Or sl(inputx(k + 2), 16) Or sl(inputx(k + 3), 24)
        i = i + 1
        j = j + 4
    Loop
End Sub

Sub MD5_memcpy(ByRef output, ByVal outputOffset, ByRef inputx, ByVal inputxOffset, ByVal lenx)
    Dim i
    For i = 0 To lenx - 1
        output(i + outputOffset) = inputx(i + inputxOffset)
    Next
End Sub

Function main(ByVal argc, ByRef argv)
    Dim i
    If argc > 1 Then
        For i = 1 To argc - 1
            If Mid(argv(i), 1, 2) = "-s" Then
                Call MDString(Mid(argv(i), 3))
            ElseIf argv(i) = "-t" Then
                ' Call MDTimeTrial
            ElseIf argv(i) = "-x" Then
                Call MDTestSuite
            Else
                ' Call MDFile(argv(i))
            End If
        Next
    Else
        ' Call MDFilter
    End If
    main = 0
End Function

Function MDString(ByVal stringx)
    Dim state(3)
    Dim count(1)
    Dim buffer(63)
    
    Dim digest(15)
    Dim lenx
    lenx = Len(stringx)

    Call MD5Init(state, count, buffer)
    Call MD5Update(state, count, buffer, ba(stringx), lenx)
    Call MD5Final(digest, state, count, buffer)

    Dim s
    s = MDPrint(digest)
    MDString = s
End Function

Sub MDTestSuite()
    Dim x
    Dim y
    Dim r
    r = ""
    
    x = ""
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "a"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "abc"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "message digest"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "abcdefghijklmnopqrstuvwxyz"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine
    
    x = "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
    y = MDString(x)
    r = r & x & ": " & y & vbNewLine

    Call MsgBox(r)
End Sub

Function MDPrint(ByRef digest)
    Dim s
    s = ""
    Dim i
    For i = 0 To 16 - 1
        s = s & Right("00" & LCase(Hex(digest(i))), 2)
    Next
    MDPrint = s
End Function

Call main(2, Array("", "-x"))

JavaScript 版

(テスト呼び出し用に WSH(Windows Scripting Host) を使っています。)
// このプログラムコードは RFC 1321 (The MD5 Message-Digest Algorithm) の参照インプリメンテーションを
// unibon が JavaScript に移植したものです。
// 権利については RFC 1321 中の記述が優先されます。
// This program code is "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm".

function add(a, b) { // オーバフローを無視して 32 ビットの加算をおこなう。
    var c = a + b;
    if (c > 2147483647) {
        c = c - 4294967296
    } else if (c < -2147483648) {
        c = c + 4294967296
    }
    return c;
}

function ba(s) { // 文字列を文字の配列に変換する。
    var a = new Array(s.length);
    for (var i = 0; i < s.length; i++) {
        a[i] = s.charCodeAt(i);
    }
    return a;
}

function FX(x, y, z) {
    return (x & y) | ((~ x) & z);
}

function GX(x, y, z) {
    return (x & z) | (y & (~ z));
}

function HX(x, y, z) {
    return x ^ y ^ z;
}

function IX(x, y, z) {
    return y ^ (x | (~ z));
}

function ROTATE_LEFT(x, n) {
    return (x << n) | (x >>> (32 - n));
}

function FF(a, b, c, d, x, s, ac) {
    a = add(add(add(a, FX(b, c, d)), x), ac);
    a = ROTATE_LEFT(a, s);
    a = add(a, b);
    return a;
}

function GG(a, b, c, d, x, s, ac) {
    a = add(add(add(a, GX(b, c, d)), x), ac);
    a = ROTATE_LEFT(a, s);
    a = add(a, b);
    return a;
}

function HH(a, b, c, d, x, s, ac) {
    a = add(add(add(a, HX(b, c, d)), x), ac);
    a = ROTATE_LEFT(a, s);
    a = add(a, b);
    return a;
}

function II(a, b, c, d, x, s, ac) {
    a = add(add(add(a, IX(b, c, d)), x), ac);
    a = ROTATE_LEFT(a, s);
    a = add(a, b);
    return a;
}

function MD5Init(state, count, buffer) {
    count[0] = 0;
    count[1] = 0;
    
    state[0] = add(0x67452301, 0);
    state[1] = add(0xEFCDAB89, 0);
    state[2] = add(0x98BADCFE, 0);
    state[3] = add(0x10325476, 0);
}

function MD5Update(state, count, buffer, inputx, inputLen) {
    var i;
    var index;
    var partLen;

    index = (count[0] >>> 3) & 0x3F;
    
    count[0] = add(count[0], (inputLen << 3));
    if (count[0] < (inputLen << 3)) {
        count[1] = add(count[1], 1);
    }

    count[1] = add(count[1], (inputLen >>> 29));

    partLen = 64 - index;

    if (inputLen >= partLen) {
        MD5_memcpy(buffer, index, inputx, 0, partLen);
        MD5Transform(state, buffer, 0);

        for (i = partLen; i < inputLen - 63; i += 64) {
            MD5Transform(state, inputx, i);
        }
        index = 0;
    } else {
        i = 0;
    }

    MD5_memcpy(buffer, index, inputx, i, inputLen - i);
}

function MD5Final(digest, state, count, buffer) {
    var bits = new Array(8);
    var index;
    var padLen;

    Encode(bits, count, 8);

    index = (count[0] >>> 3) & 0x3F;
    if (index < 56) {
        padLen = 56 - index;
    } else {
        padLen = 120 - index;
    }
    
    var PADDING = new Array(64);
    for (var i = 0; i < PADDING.length; i++) {
        PADDING[i] = 0;
    }
    PADDING[0] = 0x80;

    MD5Update(state, count, buffer, PADDING, padLen);

    MD5Update(state, count, buffer, bits, 8);

    Encode(digest, state, 16);
    
    for (var i = 0; i < state.length; i++) {
        state[i] = 0;
    }
    for (var i = 0; i < count.length; i++) {
        count[i] = 0;
    }
    for (var i = 0; i < buffer.length; i++) {
        buffer[i] = 0;
    }
}

function MD5Transform(state, block, offset) {
    var a = state[0];
    var b = state[1];
    var c = state[2];
    var d = state[3];
    
    var x = new Array(16);
    Decode(x, block, offset, 64);

    // Round 1
    a = FF(a, b, c, d, x[ 0],  7, 0xD76AA478); //  1 S11
    d = FF(d, a, b, c, x[ 1], 12, 0xE8C7B756); //  2 S12
    c = FF(c, d, a, b, x[ 2], 17, 0x242070DB); //  3 S13
    b = FF(b, c, d, a, x[ 3], 22, 0xC1BDCEEE); //  4 S14
    a = FF(a, b, c, d, x[ 4],  7, 0xF57C0FAF); //  5 S11
    d = FF(d, a, b, c, x[ 5], 12, 0x4787C62A); //  6 S12
    c = FF(c, d, a, b, x[ 6], 17, 0xA8304613); //  7 S13
    b = FF(b, c, d, a, x[ 7], 22, 0xFD469501); //  8 S14
    a = FF(a, b, c, d, x[ 8],  7, 0x698098D8); //  9 S11
    d = FF(d, a, b, c, x[ 9], 12, 0x8B44F7AF); // 10 S12
    c = FF(c, d, a, b, x[10], 17, 0xFFFF5BB1); // 11 S13
    b = FF(b, c, d, a, x[11], 22, 0x895CD7BE); // 12 S14
    a = FF(a, b, c, d, x[12],  7, 0x6B901122); // 13 S11
    d = FF(d, a, b, c, x[13], 12, 0xFD987193); // 14 S12
    c = FF(c, d, a, b, x[14], 17, 0xA679438E); // 15 S13
    b = FF(b, c, d, a, x[15], 22, 0x49B40821); // 16 S14

    // Round 2
    a = GG(a, b, c, d, x[ 1],  5, 0xF61E2562); // 17 S21
    d = GG(d, a, b, c, x[ 6],  9, 0xC040B340); // 18 S22
    c = GG(c, d, a, b, x[11], 14, 0x265E5A51); // 19 S23
    b = GG(b, c, d, a, x[ 0], 20, 0xE9B6C7AA); // 20 S24
    a = GG(a, b, c, d, x[ 5],  5, 0xD62F105D); // 21 S21
    d = GG(d, a, b, c, x[10],  9,  0x2441453); // 22 S22
    c = GG(c, d, a, b, x[15], 14, 0xD8A1E681); // 23 S23
    b = GG(b, c, d, a, x[ 4], 20, 0xE7D3FBC8); // 24 S24
    a = GG(a, b, c, d, x[ 9],  5, 0x21E1CDE6); // 25 S21
    d = GG(d, a, b, c, x[14],  9, 0xC33707D6); // 26 S22
    c = GG(c, d, a, b, x[ 3], 14, 0xF4D50D87); // 27 S23
    b = GG(b, c, d, a, x[ 8], 20, 0x455A14ED); // 28 S24
    a = GG(a, b, c, d, x[13],  5, 0xA9E3E905); // 29 S21
    d = GG(d, a, b, c, x[ 2],  9, 0xFCEFA3F8); // 30 S22
    c = GG(c, d, a, b, x[ 7], 14, 0x676F02D9); // 31 S23
    b = GG(b, c, d, a, x[12], 20, 0x8D2A4C8A); // 32 S24

    // Round 3
    a = HH(a, b, c, d, x[ 5],  4, 0xFFFA3942); // 33 S31
    d = HH(d, a, b, c, x[ 8], 11, 0x8771F681); // 34 S32
    c = HH(c, d, a, b, x[11], 16, 0x6D9D6122); // 35 S33
    b = HH(b, c, d, a, x[14], 23, 0xFDE5380C); // 36 S34
    a = HH(a, b, c, d, x[ 1],  4, 0xA4BEEA44); // 37 S31
    d = HH(d, a, b, c, x[ 4], 11, 0x4BDECFA9); // 38 S32
    c = HH(c, d, a, b, x[ 7], 16, 0xF6BB4B60); // 39 S33
    b = HH(b, c, d, a, x[10], 23, 0xBEBFBC70); // 40 S34
    a = HH(a, b, c, d, x[13],  4, 0x289B7EC6); // 41 S31
    d = HH(d, a, b, c, x[ 0], 11, 0xEAA127FA); // 42 S32
    c = HH(c, d, a, b, x[ 3], 16, 0xD4EF3085); // 43 S33
    b = HH(b, c, d, a, x[ 6], 23,  0x4881D05); // 44 S34
    a = HH(a, b, c, d, x[ 9],  4, 0xD9D4D039); // 45 S31
    d = HH(d, a, b, c, x[12], 11, 0xE6DB99E5); // 46 S32
    c = HH(c, d, a, b, x[15], 16, 0x1FA27CF8); // 47 S33
    b = HH(b, c, d, a, x[ 2], 23, 0xC4AC5665); // 48 S34

    // Round 4
    a = II(a, b, c, d, x[ 0],  6, 0xF4292244); // 49 S41
    d = II(d, a, b, c, x[ 7], 10, 0x432AFF97); // 50 S42
    c = II(c, d, a, b, x[14], 15, 0xAB9423A7); // 51 S43
    b = II(b, c, d, a, x[ 5], 21, 0xFC93A039); // 52 S44
    a = II(a, b, c, d, x[12],  6, 0x655B59C3); // 53 S41
    d = II(d, a, b, c, x[ 3], 10, 0x8F0CCC92); // 54 S42
    c = II(c, d, a, b, x[10], 15, 0xFFEFF47D); // 55 S43
    b = II(b, c, d, a, x[ 1], 21, 0x85845DD1); // 56 S44
    a = II(a, b, c, d, x[ 8],  6, 0x6FA87E4F); // 57 S41
    d = II(d, a, b, c, x[15], 10, 0xFE2CE6E0); // 58 S42
    c = II(c, d, a, b, x[ 6], 15, 0xA3014314); // 59 S43
    b = II(b, c, d, a, x[13], 21, 0x4E0811A1); // 60 S44
    a = II(a, b, c, d, x[ 4],  6, 0xF7537E82); // 61 S41
    d = II(d, a, b, c, x[11], 10, 0xBD3AF235); // 62 S42
    c = II(c, d, a, b, x[ 2], 15, 0x2AD7D2BB); // 63 S43
    b = II(b, c, d, a, x[ 9], 21, 0xEB86D391); // 64 S44

    state[0] = add(state[0], a);
    state[1] = add(state[1], b);
    state[2] = add(state[2], c);
    state[3] = add(state[3], d);

    for (var i = 0; i < x.length; i++) {
        x[i] = 0;
    }
}

function Encode(output, inputx, lenx) {
    var i = 0;
    var j = 0;
    while (j < lenx) {
        output[j] = inputx[i] & 0xFF;
        output[j + 1] = (inputx[i] >>> 8) & 0xFF;
        output[j + 2] = (inputx[i] >>> 16) & 0xFF;
        output[j + 3] = (inputx[i] >>> 24) & 0xFF;
        i++;
        j += 4;
    }
}

function Decode(output, inputx, inputxOffset, lenx) {
    var i = 0;
    var j = 0;
    while (j < lenx) {
        var k = j + inputxOffset;
        output[i] = inputx[k] | (inputx[k + 1] << 8) | (inputx[k + 2] << 16) | (inputx[k + 3] << 24);
        i++;
        j += 4;
    }
}

function MD5_memcpy(output, outputOffset, inputx, inputxOffset, lenx) {
    for (var i = 0; i < lenx; i++) {
        output[i + outputOffset] = inputx[i + inputxOffset];
    }
}

function main(argc, argv) {
    if (argc > 1) {
        for (var i = 1; i < argc; i++) {
            if (argv[i].substring(0, 2) == "-s") {
                MDString(argv[i].substring(2, argv[i].length));
            } else if (argv[i].substring(0, 2) == "-t") {
                // MDTimeTrial();
            } else if (argv[i].substring(0, 2) == "-x") {
                MDTestSuite();
            } else {
                // MDFile(argv[i]);
            }
        }
    } else {
        // MDFilter();
    }
    return 0;
}

function MDString(stringx) {
    var state = new Array(4);
    var count = new Array(2);
    var buffer = new Array(64);

    var digest = new Array(16);
    var lenx = stringx.length;

    MD5Init(state, count, buffer);
    MD5Update(state, count, buffer, ba(stringx), lenx);
    MD5Final(digest, state, count, buffer);

    var s = MDPrint(digest);
    return s;
}

function MDTestSuite() {
    var x;
    var y;
    
    var r = "";

    x = "";
    y = MDString(x);
    r += x + ": " + y + "\n";
    
    x = "a";
    y = MDString(x);
    r += x + ": " + y + "\n";

    x = "abc";
    y = MDString(x);
    r += x + ": " + y + "\n";
    
    x = "message digest";
    y = MDString(x);
    r += x + ": " + y + "\n";
    
    x = "abcdefghijklmnopqrstuvwxyz";
    y = MDString(x);
    r += x + ": " + y + "\n";
    
    x = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    y = MDString(x);
    r += x + ": " + y + "\n";
    
    x = "12345678901234567890123456789012345678901234567890123456789012345678901234567890";
    y = MDString(x);
    r += x + ": " + y + "\n";

    WScript.Echo(r);
}

function MDPrint(digest) {
    var s = "";
    for (var i = 0; i < 16; i++) {
        var t = "00" + digest[i].toString(16);
        s += t.substring(t.length - 2, t.length);
    }
    return s;
}

var argc = 2;
var args = new Array(argc);
args[0] = "";
args[1] = "-x";
main(argc, args);

ASP の目次
ホーム
(このページ自身の絶対的な URL)