15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The original source code is from:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://src.chromium.org/viewvc/chrome/trunk/src/base/md5_unittest.cc?revision=94203
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "util/md5.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libaddressinput/util/scoped_ptr.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::MD5Context;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::MD5Digest;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::MD5Init;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::MD5String;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::MD5Update;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using i18n::addressinput::scoped_ptr;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(MD5, DigestToBase16) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Digest digest;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int data[] = {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd4, 0x1d, 0x8c, 0xd9,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x8f, 0x00, 0xb2, 0x04,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xe9, 0x80, 0x09, 0x98,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xec, 0xf8, 0x42, 0x7e
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 16; ++i)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    digest.a[i] = data[i] & 0xff;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string actual = MD5DigestToBase16(digest);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string expected = "d41d8cd98f00b204e9800998ecf8427e";
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected, actual);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MD5, MD5SumEmtpyData) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Digest digest;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* data = "";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Sum(data, strlen(data), &digest);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected[] = {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xd4, 0x1d, 0x8c, 0xd9,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    0x8f, 0x00, 0xb2, 0x04,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xe9, 0x80, 0x09, 0x98,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xec, 0xf8, 0x42, 0x7e
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 16; ++i)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(MD5, MD5SumOneByteData) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Digest digest;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* data = "a";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MD5Sum(data, strlen(data), &digest);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int expected[] = {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x0c, 0xc1, 0x75, 0xb9,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0xc0, 0xf1, 0xb6, 0xa8,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x31, 0xc3, 0x99, 0xe2,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0x69, 0x77, 0x26, 0x61
73  };
74
75  for (int i = 0; i < 16; ++i)
76    EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
77}
78
79TEST(MD5, MD5SumLongData) {
80  const int length = 10 * 1024 * 1024 + 1;
81  scoped_ptr<char[]> data(new char[length]);
82
83  for (int i = 0; i < length; ++i)
84    data[i] = i & 0xFF;
85
86  MD5Digest digest;
87  MD5Sum(data.get(), length, &digest);
88
89  int expected[] = {
90    0x90, 0xbd, 0x6a, 0xd9,
91    0x0a, 0xce, 0xf5, 0xad,
92    0xaa, 0x92, 0x20, 0x3e,
93    0x21, 0xc7, 0xa1, 0x3e
94  };
95
96  for (int i = 0; i < 16; ++i)
97    EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
98}
99
100TEST(MD5, ContextWithEmptyData) {
101  MD5Context ctx;
102  MD5Init(&ctx);
103
104  MD5Digest digest;
105  MD5Final(&digest, &ctx);
106
107  int expected[] = {
108    0xd4, 0x1d, 0x8c, 0xd9,
109    0x8f, 0x00, 0xb2, 0x04,
110    0xe9, 0x80, 0x09, 0x98,
111    0xec, 0xf8, 0x42, 0x7e
112  };
113
114  for (int i = 0; i < 16; ++i)
115    EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
116}
117
118TEST(MD5, ContextWithLongData) {
119  MD5Context ctx;
120  MD5Init(&ctx);
121
122  const int length = 10 * 1024 * 1024 + 1;
123  scoped_ptr<char[]> data(new char[length]);
124
125  for (int i = 0; i < length; ++i)
126    data[i] = i & 0xFF;
127
128  int total = 0;
129  while (total < length) {
130    int len = 4097;  // intentionally not 2^k.
131    if (len > length - total)
132      len = length - total;
133
134    MD5Update(&ctx,
135              std::string(reinterpret_cast<char*>(data.get() + total), len));
136    total += len;
137  }
138
139  EXPECT_EQ(length, total);
140
141  MD5Digest digest;
142  MD5Final(&digest, &ctx);
143
144  int expected[] = {
145    0x90, 0xbd, 0x6a, 0xd9,
146    0x0a, 0xce, 0xf5, 0xad,
147    0xaa, 0x92, 0x20, 0x3e,
148    0x21, 0xc7, 0xa1, 0x3e
149  };
150
151  for (int i = 0; i < 16; ++i)
152    EXPECT_EQ(expected[i], digest.a[i] & 0xFF);
153}
154
155// Example data from http://www.ietf.org/rfc/rfc1321.txt A.5 Test Suite
156TEST(MD5, MD5StringTestSuite1) {
157  std::string actual = MD5String("");
158  std::string expected = "d41d8cd98f00b204e9800998ecf8427e";
159  EXPECT_EQ(expected, actual);
160}
161
162TEST(MD5, MD5StringTestSuite2) {
163  std::string actual = MD5String("a");
164  std::string expected = "0cc175b9c0f1b6a831c399e269772661";
165  EXPECT_EQ(expected, actual);
166}
167
168TEST(MD5, MD5StringTestSuite3) {
169  std::string actual = MD5String("abc");
170  std::string expected = "900150983cd24fb0d6963f7d28e17f72";
171  EXPECT_EQ(expected, actual);
172}
173
174TEST(MD5, MD5StringTestSuite4) {
175  std::string actual = MD5String("message digest");
176  std::string expected = "f96b697d7cb7938d525a2f31aaf161d0";
177  EXPECT_EQ(expected, actual);
178}
179
180TEST(MD5, MD5StringTestSuite5) {
181  std::string actual = MD5String("abcdefghijklmnopqrstuvwxyz");
182  std::string expected = "c3fcd3d76192e4007dfb496cca67e13b";
183  EXPECT_EQ(expected, actual);
184}
185
186TEST(MD5, MD5StringTestSuite6) {
187  std::string actual = MD5String("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
188                                 "abcdefghijklmnopqrstuvwxyz"
189                                 "0123456789");
190  std::string expected = "d174ab98d277d9f5a5611c2c9f419d9f";
191  EXPECT_EQ(expected, actual);
192}
193
194TEST(MD5, MD5StringTestSuite7) {
195  std::string actual = MD5String("12345678901234567890"
196                                 "12345678901234567890"
197                                 "12345678901234567890"
198                                 "12345678901234567890");
199  std::string expected = "57edf4a22be3c955ac49da2e2107b67a";
200  EXPECT_EQ(expected, actual);
201}
202
203TEST(MD5, ContextWithStringData) {
204  MD5Context ctx;
205  MD5Init(&ctx);
206
207  MD5Update(&ctx, "abc");
208
209  MD5Digest digest;
210  MD5Final(&digest, &ctx);
211
212  std::string actual = MD5DigestToBase16(digest);
213  std::string expected = "900150983cd24fb0d6963f7d28e17f72";
214
215  EXPECT_EQ(expected, actual);
216}
217
218}  // namespace
219