/// <summary> /// MD5の計算を追記する関数(Streamタイプ) /// 64bytesごとに計算して保持しておく /// </summary> /// <param name="md5">MD5クラスを指定する</param> /// <param name="input">入力するストリーム</param> public static void MD5Add(MD5Data md5, Stream input) { int blockSize = 64; int buffSize = blockSize; int startPoint = 0; int readLen; byte[] vs = new byte[blockSize]; if (md5.BytesPtr != 0) { // byte[] bt = new byte[md5.BytesPtr]; Buffer.BlockCopy(md5.Bytes, 0, vs, 0, md5.BytesPtr); buffSize = blockSize - md5.BytesPtr; startPoint = md5.BytesPtr; } while (true) { readLen = input.Read(vs, startPoint, buffSize); if (readLen > 0) { if (readLen + startPoint == blockSize) { //処理本体 md5.words = CalcPart(md5.words, vs); md5.DataLen += 64; } else if (readLen + startPoint < blockSize) { break; } } else { break; } buffSize = blockSize; startPoint = 0; } if (readLen + startPoint > 0) { md5.BytesPtr = readLen + startPoint % 64; if (md5.BytesPtr != 0) { Buffer.BlockCopy(vs, 0, md5.Bytes, 0, md5.BytesPtr); } } }
/// <summary> /// MD5の計算を追記する関数(byte[]タイプ) /// 64bytesごとに計算して保持しておく /// </summary> /// <param name="md5">MD5クラスを指定する</param> /// <param name="input">入力するバイト列</param> public static void MD5Add(MD5Data md5, byte[] input) { byte[] vs; //前回の余りデータがあれば結合する if (md5.BytesPtr != 0) { byte[] bt = new byte[md5.BytesPtr]; Buffer.BlockCopy(md5.Bytes, 0, bt, 0, md5.BytesPtr); vs = (bt).Concat(input).ToArray(); } //なければそのまま else { vs = input; } //処理長さを保持 //int tempLen = input.Length; int tempLen = vs.Length; //64Bytesごとに処理 for (int i = 0; i < (tempLen / 64); i++) { //処理本体 byte[] b = new byte[64]; //Buffer.BlockCopy(input, i * 64, b, 0, 64); Buffer.BlockCopy(vs, i * 64, b, 0, 64); md5.words = CalcPart(md5.words, b); //長さの反映 md5.DataLen += 64; } //余りがあったら処理 md5.BytesPtr = tempLen % 64; if (md5.BytesPtr != 0) { //Buffer.BlockCopy(input, (tempLen / 64) * 64, md5.Bytes, 0, md5.BytesPtr); Buffer.BlockCopy(vs, (tempLen / 64) * 64, md5.Bytes, 0, md5.BytesPtr); } }
static void Main(string[] args) { string mes = "message "; string mes2 = "digest"; MD5Data m = MD5Init(); MD5Add(m, System.Text.Encoding.ASCII.GetBytes(mes)); byte[] sb = System.Text.Encoding.ASCII.GetBytes(mes2); MemoryStream st = new MemoryStream(sb); MD5Add(m, st); string md5 = MD5Final(m); Console.WriteLine(md5); }
/// <summary> /// MD5計算の初期値を代入する関数 /// </summary> public static MD5Data MD5Init() { MD5Data initData = new MD5Data(); return(initData); }
/// <summary> /// MD5の計算を終了し、結果を返す関数 /// パディング処理、結果の変換 /// </summary> /// <returns>MD5計算値</returns> public static string MD5Final(MD5Data md5) { byte[] bs = new byte[64]; int ptr = md5.BytesPtr; //md5.Bytes.CopyTo(bs, 0); //long ptr = md5.BytesPtr; Buffer.BlockCopy(md5.Bytes, 0, bs, 0, ptr); //int padLen = (int)(md5.DataLen % 64); int padLen = ptr; if (padLen < 56) { padLen = 56 - padLen; } else { padLen = 64 + 56 - padLen; } if (padLen > 0) { bs[ptr++] = 0x80; for (int i = 1; i < padLen; i++) { bs[ptr++] = 0x00; } } //Byteからbitに変換 long originLen = (md5.DataLen + md5.BytesPtr) * 8; //長さ情報をbyte配列に入れる UInt32 lenLSB = (UInt32)(originLen & 0xFFFFFFFF); UInt32 lenMSB = (UInt32)(originLen >> 32); byte[] len = BitConverter.GetBytes(lenLSB); len.CopyTo(bs, ptr); ptr += 4; len = BitConverter.GetBytes(lenMSB); len.CopyTo(bs, ptr); ptr += 4; md5.words = CalcPart(md5.words, bs); //UInt32 -> Byte[] byte[] bArrayA = BitConverter.GetBytes(md5.words[0]); byte[] bArrayB = BitConverter.GetBytes(md5.words[1]); byte[] bArrayC = BitConverter.GetBytes(md5.words[2]); byte[] bArrayD = BitConverter.GetBytes(md5.words[3]); //Byte配列に格納 byte[] bArray = new byte[16]; bArrayA.CopyTo(bArray, 0); bArrayB.CopyTo(bArray, 4); bArrayC.CopyTo(bArray, 8); bArrayD.CopyTo(bArray, 12); return(BitConverter.ToString(bArray).Replace("-", "")); }