File: md5.h

package info (click to toggle)
widelands 1:19+repack-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 370,608 kB
  • ctags: 20,609
  • sloc: cpp: 108,404; ansic: 18,695; python: 5,155; sh: 487; xml: 460; makefile: 233
file content (131 lines) | stat: -rw-r--r-- 3,654 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Thanks to Ulrich Drepper for the md5sum example code
 *
 * Copyright (C) 2002, 2007-2008 by the Widelands Development Team
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#ifndef WL_BASE_MD5_H
#define WL_BASE_MD5_H

#include <cassert>
#include <cstring>
#include <string>

#include <stdint.h>

/* Structure to save state of computation between the single steps.  */
struct Md5Ctx {
	uint32_t A;
	uint32_t B;
	uint32_t C;
	uint32_t D;

	uint32_t total[2];
	uint32_t buflen;
	char buffer[128];
};

/**
 * One MD5 checksum is simply an array of 16 bytes.
 */
struct Md5Checksum {
	uint8_t data[16];

	std::string str() const;

	bool operator==(const Md5Checksum& o) const {
		return memcmp(data, o.data, sizeof(data)) == 0;
	}

	bool operator!=(const Md5Checksum& o) const {
		return !(*this == o);
	}
};

// Note that the implementation of MD5Checksum is basically just
// a wrapper around these functions, which have been taken basically
// verbatim (with some whitespace changes) from the GNU tools; see below.
void* md5_finish_ctx(Md5Ctx*, void* resbuf);
void md5_process_bytes(void const* buffer, uint32_t len, Md5Ctx*);
void md5_process_block(void const* buffer, uint32_t len, Md5Ctx*);

/**
 * This class is responsible for creating a streaming md5 checksum.
 * You simply pass it the data using stream operations, and if you want
 * to read the checksum, first call finish_checksum(), followed by
 * get_checksum().
 *
 * Instances of this class can be copied.
 */
template <typename Base> class MD5Checksum : public Base {
public:
	MD5Checksum() {
		Reset();
	}
	explicit MD5Checksum(const MD5Checksum& other)
	   : Base(), can_handle_data(other.can_handle_data), sum(other.sum), ctx(other.ctx) {
	}

	/// Reset the checksumming machinery to its initial state.
	void Reset() {
		can_handle_data = 1;
		ctx.A = 0x67452301;
		ctx.B = 0xefcdab89;
		ctx.C = 0x98badcfe;
		ctx.D = 0x10325476;
		ctx.total[0] = ctx.total[1] = 0;
		ctx.buflen = 0;
	}

	/// This function consumes new data. It buffers it and calculates one MD5
	/// block when the buffer is full.
	///
	/// \param newdata data to compute chksum for
	/// \param size size of data
	void data(const void* const newdata, const size_t size) {
		assert(can_handle_data);
		md5_process_bytes(newdata, size, &ctx);
	}

	/// This function finishes the checksum calculation.
	/// After this, no more data may be written to the checksum.
	void finish_checksum() {
		assert(can_handle_data);
		can_handle_data = 0;
		md5_finish_ctx(&ctx, sum.data);
	}

	/// Retrieve the checksum. Note that \ref finish_checksum must be called
	/// before this function.
	///
	/// \return a pointer to an array of 16 bytes containing the checksum.
	const Md5Checksum& get_checksum() const {
		assert(!can_handle_data);
		return sum;
	}

private:
	bool can_handle_data;
	Md5Checksum sum;
	Md5Ctx ctx;
};

class _DummyMD5Base {};
using SimpleMD5Checksum = MD5Checksum<_DummyMD5Base>;

#endif  // end of include guard: WL_BASE_MD5_H