Skip to content

Commit 69279c5

Browse files
committed
CDRIVER-2671 swap MD5 with FNV-1a in ObjectIDs
1 parent 57b3497 commit 69279c5

File tree

13 files changed

+365
-23
lines changed

13 files changed

+365
-23
lines changed

src/libbson/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ set (SOURCES
162162
${PROJECT_SOURCE_DIR}/src/bson/bson-context.c
163163
${PROJECT_SOURCE_DIR}/src/bson/bson-decimal128.c
164164
${PROJECT_SOURCE_DIR}/src/bson/bson-error.c
165+
${PROJECT_SOURCE_DIR}/src/bson/bson-fnv.c
165166
${PROJECT_SOURCE_DIR}/src/bson/bson-iso8601.c
166167
${PROJECT_SOURCE_DIR}/src/bson/bson-iter.c
167168
${PROJECT_SOURCE_DIR}/src/bson/bson-json.c

src/libbson/THIRD_PARTY_NOTICES

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,21 @@ freely, subject to the following restrictions:
5252

5353
L. Peter Deutsch
5454
55+
56+
57+
License notice for bson-fnv-private.h, bson-fnv.c and test-fnv.c
58+
-------------------------------------------------------------------------------
59+
60+
Please do not copyright this code. This code is in the public domain.
61+
62+
LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
63+
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
64+
EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
65+
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
66+
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
67+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
68+
PERFORMANCE OF THIS SOFTWARE.
69+
70+
By:
71+
chongo <Landon Curt Noll> /\oo/\
72+
http://www.isthe.com/chongo/

src/libbson/doc/bson_md5_t.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Synopsis
1919
Description
2020
-----------
2121

22-
bson_md5_t encapsulates an implementation of the MD5 algorithm. This is used in OID generation for the MD5(hostname) bytes. It is also used by some libraries such as the MongoDB C driver.
22+
bson_md5_t encapsulates an implementation of the MD5 algorithm.
2323

2424
.. only:: html
2525

src/libbson/doc/oid.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Composition
1111
-----------
1212

1313
* 4 bytes : The UNIX timestamp in big-endian format.
14-
* 3 bytes : The first 3 bytes of ``MD5(hostname)``.
14+
* 3 bytes : A hash of the hostname.
1515
* 2 bytes : The ``pid_t`` of the current process. Alternatively the task-id if configured.
1616
* 3 bytes : A 24-bit monotonic counter incrementing from ``rand()`` in big-endian.
1717

src/libbson/src/bson/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set (src_libbson_src_bson_DIST_hs
2525
bson-private.h
2626
bson-iso8601-private.h
2727
bson-context-private.h
28+
bson-fnv-private.h
2829
bson-thread-private.h
2930
bson-timegm-private.h
3031
)
@@ -40,6 +41,7 @@ set (src_libbson_src_bson_DIST_cs
4041
bson-context.c
4142
bson-decimal128.c
4243
bson-error.c
44+
bson-fnv.c
4345
bson-iter.c
4446
bson-iso8601.c
4547
bson-json.c

src/libbson/src/bson/bson-context-private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct _bson_context_t {
3131
int flags : 7;
3232
bool pidbe_once : 1;
3333
uint8_t pidbe[2];
34-
uint8_t md5[3];
34+
uint8_t fnv[3];
3535
int32_t seq32;
3636
int64_t seq64;
3737

src/libbson/src/bson/bson-context.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "bson-clock.h"
2727
#include "bson-context.h"
2828
#include "bson-context-private.h"
29-
#include "bson-md5.h"
29+
#include "bson-fnv-private.h"
3030
#include "bson-memory.h"
3131
#include "bson-thread-private.h"
3232

@@ -60,7 +60,7 @@ bson_gettid (void)
6060
*
6161
* _bson_context_get_oid_host --
6262
*
63-
* Retrieves the first three bytes of MD5(hostname) and assigns them
63+
* Retrieves a 3 byte hash of the hostname and assigns those bytes
6464
* to the host portion of oid.
6565
*
6666
* Returns:
@@ -77,8 +77,7 @@ _bson_context_get_oid_host (bson_context_t *context, /* IN */
7777
bson_oid_t *oid) /* OUT */
7878
{
7979
uint8_t *bytes = (uint8_t *) oid;
80-
uint8_t digest[16];
81-
bson_md5_t md5;
80+
uint32_t fnv1a_hash;
8281
char hostname[HOST_NAME_MAX];
8382

8483
BSON_ASSERT (context);
@@ -87,14 +86,11 @@ _bson_context_get_oid_host (bson_context_t *context, /* IN */
8786
gethostname (hostname, sizeof hostname);
8887
hostname[HOST_NAME_MAX - 1] = '\0';
8988

90-
bson_md5_init (&md5);
91-
bson_md5_append (
92-
&md5, (const uint8_t *) hostname, (uint32_t) strlen (hostname));
93-
bson_md5_finish (&md5, &digest[0]);
89+
fnv1a_hash = _mongoc_fnv_24a_str (hostname);
9490

95-
bytes[4] = digest[0];
96-
bytes[5] = digest[1];
97-
bytes[6] = digest[2];
91+
bytes[4] = (uint8_t) ((fnv1a_hash >> (0 * 8)) & 0xff);
92+
bytes[5] = (uint8_t) ((fnv1a_hash >> (1 * 8)) & 0xff);
93+
bytes[6] = (uint8_t) ((fnv1a_hash >> (2 * 8)) & 0xff);
9894
}
9995

10096

@@ -103,7 +99,7 @@ _bson_context_get_oid_host (bson_context_t *context, /* IN */
10399
*
104100
* _bson_context_get_oid_host_cached --
105101
*
106-
* Fetch the cached copy of the MD5(hostname).
102+
* Fetch the cached copy of the 3 byte hash of the hostname
107103
*
108104
* Returns:
109105
* None.
@@ -121,9 +117,9 @@ _bson_context_get_oid_host_cached (bson_context_t *context, /* IN */
121117
BSON_ASSERT (context);
122118
BSON_ASSERT (oid);
123119

124-
oid->bytes[4] = context->md5[0];
125-
oid->bytes[5] = context->md5[1];
126-
oid->bytes[6] = context->md5[2];
120+
oid->bytes[4] = context->fnv[0];
121+
oid->bytes[5] = context->fnv[1];
122+
oid->bytes[6] = context->fnv[2];
127123
}
128124

129125

@@ -364,9 +360,9 @@ _bson_context_init (bson_context_t *context, /* IN */
364360
context->oid_get_host = _bson_context_get_oid_host;
365361
} else {
366362
_bson_context_get_oid_host (context, &oid);
367-
context->md5[0] = oid.bytes[4];
368-
context->md5[1] = oid.bytes[5];
369-
context->md5[2] = oid.bytes[6];
363+
context->fnv[0] = oid.bytes[4];
364+
context->fnv[1] = oid.bytes[5];
365+
context->fnv[2] = oid.bytes[6];
370366
}
371367

372368
if ((flags & BSON_CONTEXT_THREAD_SAFE)) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Please do not copyright this code. This code is in the public domain.
3+
*
4+
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
5+
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
6+
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
7+
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
8+
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
9+
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
10+
* PERFORMANCE OF THIS SOFTWARE.
11+
*
12+
* By:
13+
* chongo <Landon Curt Noll> /\oo/\
14+
* http://www.isthe.com/chongo/
15+
*/
16+
17+
#ifndef MONGO_C_DRIVER_BSON_FNV_PRIVATE_H
18+
#define MONGO_C_DRIVER_BSON_FNV_PRIVATE_H
19+
20+
#include "bson.h"
21+
22+
uint32_t
23+
_mongoc_fnv_24a_str (char *str);
24+
25+
#endif /* MONGO_C_DRIVER_BSON_FNV_PRIVATE_H */

src/libbson/src/bson/bson-fnv.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Please do not copyright this code. This code is in the public domain.
3+
*
4+
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
5+
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
6+
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
7+
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
8+
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
9+
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
10+
* PERFORMANCE OF THIS SOFTWARE.
11+
*
12+
* By:
13+
* chongo <Landon Curt Noll> /\oo/\
14+
* http://www.isthe.com/chongo/
15+
*/
16+
17+
/*
18+
* Sources: http://www.isthe.com/chongo/src/fnv/hash_32a.c
19+
* http://www.isthe.com/chongo/tech/comp/fnv/index.html#xor-fold
20+
*/
21+
22+
#include "bson-fnv-private.h"
23+
24+
/*
25+
* 32 bit FNV-1a non-zero initial basis
26+
*
27+
* The FNV-1 initial basis is the FNV-0 hash of the following 32 octets:
28+
*
29+
* chongo <Landon Curt Noll> /\../\
30+
*
31+
* NOTE: The \'s above are not back-slashing escape characters.
32+
* They are literal ASCII backslash 0x5c characters.
33+
*
34+
* NOTE: The FNV-1a initial basis is the same value as FNV-1 by definition.
35+
*/
36+
#define FNV1_32A_INIT ((uint32_t) 0x811c9dc5)
37+
38+
/*
39+
* 32 bit magic FNV-1a prime
40+
* NOTE: define NO_FNV_GCC_OPTIMIZATION to use this prime
41+
*/
42+
#define FNV_32_PRIME ((Fnv32_t) 0x01000193)
43+
44+
/*
45+
* For producing 24 bit FNV-1a hash using xor-fold on a 32 bit FNV-1a hash
46+
*/
47+
#define MASK_24 (((uint32_t) 1 << 24) - 1) /* i.e., (uint32_t) 0xffffff */
48+
49+
/*---------------------------------------------------------------------------
50+
*
51+
* _mongoc_fnv_24a_str --
52+
*
53+
* perform a 32 bit Fowler/Noll/Vo FNV-1a hash on a string and
54+
* xor-fold it into a 24 bit hash
55+
*
56+
* Return:
57+
* 24 bit hash as a static hash type
58+
*
59+
* Note:
60+
* input strings with multiple null characters will stop being
61+
* processed at the first null
62+
*
63+
*--------------------------------------------------------------------------
64+
*/
65+
uint32_t
66+
_mongoc_fnv_24a_str (char *str)
67+
{
68+
uint32_t hval = FNV1_32A_INIT; /* initial 32 bit hash basis */
69+
unsigned char *s = (unsigned char *) str; /* unsigned string */
70+
71+
/* FNV-1a hash each octet in the buffer */
72+
while (*s) {
73+
/* xor the bottom with the current octet */
74+
hval ^= (uint32_t) *s++;
75+
76+
/* multiply by the 32 bit FNV magic prime mod 2^32 */
77+
#if defined(NO_FNV_GCC_OPTIMIZATION)
78+
hval *= FNV_32_PRIME;
79+
#else
80+
hval +=
81+
(hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
82+
#endif
83+
}
84+
85+
/* xor-fold the result to a 24 bit value */
86+
hval = (hval >> 24) ^ (hval & MASK_24);
87+
88+
/* return our new 24 bit hash value */
89+
return hval;
90+
}

src/libbson/src/bson/bson-oid.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include <string.h>
2323

2424
#include "bson-context-private.h"
25-
#include "bson-md5.h"
2625
#include "bson-oid.h"
2726
#include "bson-string.h"
2827

@@ -134,7 +133,7 @@ bson_oid_init_sequence (bson_oid_t *oid, /* OUT */
134133
*
135134
* Generates bytes for a new bson_oid_t and stores them in @oid. The
136135
* bytes will be generated according to the specification and includes
137-
* the current time, first 3 bytes of MD5(hostname), pid (or tid), and
136+
* the current time, a 3 byte hash of the hostname, pid (or tid), and
138137
* monotonic counter.
139138
*
140139
* The bson_oid_t generated by this function is not guaranteed to be

0 commit comments

Comments
 (0)