| rfc9923v1.txt | rfc9923.txt | |||
|---|---|---|---|---|
| skipping to change at line 181 ¶ | skipping to change at line 181 ¶ | |||
| * the "calc" C-style calculator [calc], | * the "calc" C-style calculator [calc], | |||
| * netnews history file Message-ID lookup functions, | * netnews history file Message-ID lookup functions, | |||
| * [FRET] - a tool to identify file data structures / help understand | * [FRET] - a tool to identify file data structures / help understand | |||
| file formats, | file formats, | |||
| * anti-spam filters, | * anti-spam filters, | |||
| * used in an implementation of libketama for use in items such as | * used in an implementation of libketama [libketama] for use in | |||
| [memcache], | items such as [memcache], | |||
| * a spellchecker programmed in Ada 95, | * a spellchecker programmed in Ada 95, | |||
| * used in the BSD IDE project [fasmlab], | * used in the BSD Integrated Development Environments (IDE) project | |||
| [fasmlab], | ||||
| * non-cryptographic file fingerprints, | * non-cryptographic file fingerprints, | |||
| * used in the deliantra game server for its shared string | * used in the deliantra game server for its shared string | |||
| implementation [deliantra], | implementation [deliantra], | |||
| * computing Unique IDs in DASM (DTN (Delay Tolerant Networking) | * computing Unique IDs in DASM (DTN (Delay Tolerant Networking) | |||
| Applications for Symbian Mobile-phones), | Applications for Symbian Mobile-phones), | |||
| * Microsoft's hash_map implementation for VC++ 2005, | * Microsoft's hash_map implementation for VC++ 2005, | |||
| * the realpath cache in PHP 5.x (php-5.2.3/TSRM/tsrm_virtual_cwd.c), | * the realpath cache in PHP 5.x (php-5.2.3/TSRM/tsrm_virtual_cwd.c), | |||
| * DNS (Domain Name System) servers, | * DNS (Domain Name System) servers, | |||
| * used to improve [Leprechaun], an extremely fast wordlist creator, | * used to improve [Leprechaun], an extremely fast wordlist creator, | |||
| * the Vely framework [Vely] for the C language, | * the Smash utility [Smash] for rapidly finding duplicate files, | |||
| * Golf language hash tables [GolfHash], | * Golf language hash tables [RimStone], | |||
| * the libsir logging library [libsir], | * the libsir logging library [libsir], | |||
| * a standard library for modern Fortran [Fortran], | * a standard library for modern Fortran [Fortran], | |||
| * to help with seeding a pseudorandom number generator [Vortetty], | ||||
| and many other uses. It is also referenced in the following | and many other uses. It is also referenced in the following | |||
| standards documents: [RFC7357], [RFC7873], and [IEEE8021Qbp]. | standards documents: [RFC7357], [RFC7873], and [IEEE8021Q-2022]. | |||
| A study has recommended FNV in connection with the IPv6 Flow Label | A study has recommended FNV in connection with the IPv6 flow label | |||
| field [IPv6flow]. Additionally, there was a proposal to use FNV for | value [IPv6flow]. Additionally, there was a proposal to use FNV for | |||
| BFD sequence number generation [ISAAC-Auth] and a recent article and | Bidirectional Forwarding Detection (BFD) sequence number generation | |||
| study on non-cryptographic hash functions [NCHF]. | [BFDseq]. [NCHF] discusses criteria for evaluating non-cryptographic | |||
| hash functions. | ||||
| If you use an FNV function in an application, you are kindly | If you use an FNV function in an application, you are kindly | |||
| requested to send an email about it to <fnvhash-mail@asthe.com> with | requested to send an email about it to <fnvhash-mail@asthe.com> with | |||
| "FNV hash function" forming part of the subject line. | "FNV hash function" forming part of the subject line. | |||
| 1.4. Why Is FNV Non-Cryptographic? | 1.4. Why Is FNV Non-Cryptographic? | |||
| A full discussion of cryptographic hash requirements and strength is | A full discussion of cryptographic hash requirements and strength is | |||
| beyond the scope of this document. However, here are three | beyond the scope of this document. However, here are three | |||
| characteristics of FNV that would generally be considered to make it | characteristics of FNV that would generally be considered to make it | |||
| skipping to change at line 279 ¶ | skipping to change at line 279 ¶ | |||
| practice for the many non-cryptographic applications of FNV (see | practice for the many non-cryptographic applications of FNV (see | |||
| Section 1.3). | Section 1.3). | |||
| 2. FNV Basics | 2. FNV Basics | |||
| This document focuses on the FNV-1a function, whose pseudocode is as | This document focuses on the FNV-1a function, whose pseudocode is as | |||
| follows: | follows: | |||
| hash = offset_basis | hash = offset_basis | |||
| for each octet_of_data to be hashed | for each octet_of_data to be hashed | |||
| hash = hash xor octet_of_data | hash = hash XOR octet_of_data | |||
| hash = hash * FNV_Prime mod 2**HashSize | hash = hash * FNV_Prime mod 2**HashSize | |||
| return hash | return hash | |||
| In the pseudocode above, hash is a power-of-2 number of bits | In the pseudocode above, hash is a power-of-2 number of bits | |||
| (HashSize is 32, 64, 128, 256, 512, or 1024), and offset_basis and | (HashSize is 32, 64, 128, 256, 512, or 1024), and offset_basis and | |||
| FNV_Prime depend on the size of hash. | FNV_Prime depend on the size of hash. | |||
| The FNV-1 algorithm is the same, including the values of offset_basis | The FNV-1 algorithm is the same, including the values of offset_basis | |||
| and FNV_Prime, except that the order of the two lines with the "xor" | and FNV_Prime, except that the order of the two lines with the "XOR" | |||
| and multiply operations is reversed. Operational experience | and multiply operations is reversed. Operational experience | |||
| indicates better hash dispersion for small amounts of data with FNV- | indicates better hash dispersion for small amounts of data with FNV- | |||
| 1a. FNV-0 is the same as FNV-1 but with offset_basis set to zero. | 1a. FNV-0 is the same as FNV-1 but with offset_basis set to zero. | |||
| FNV-1a is suggested for general use. | FNV-1a is suggested for general use. | |||
| 2.1. FNV Primes | 2.1. FNV Primes | |||
| The theory behind FNV_Primes is beyond the scope of this document, | The theory behind FNV_Primes is beyond the scope of this document, | |||
| but the basic property to look for is how an FNV_Prime would impact | but the basic property to look for is how an FNV_Prime would impact | |||
| dispersion. Now, consider any n-bit FNV hash where n >= 32 and is | dispersion. Now, consider any n-bit FNV hash where n >= 32 and is | |||
| skipping to change at line 311 ¶ | skipping to change at line 311 ¶ | |||
| * When s is an integer and 4 < s < 11, FNV_Prime is the smallest | * When s is an integer and 4 < s < 11, FNV_Prime is the smallest | |||
| prime p of the form: | prime p of the form: | |||
| 256**int((5 + 2**s)/12) + 2**8 + b | 256**int((5 + 2**s)/12) + 2**8 + b | |||
| * where b is an integer such that: | * where b is an integer such that: | |||
| 0 < b < 2**8 | 0 < b < 2**8 | |||
| * The number of one-bits in b is four or five | * The number of one bits in b is four or five | |||
| * and where | * and where | |||
| ( p mod (2**40 - 2**24 - 1) ) > ( 2**24 + 2**8 + 2**7 ) | ( p mod (2**40 - 2**24 - 1) ) > ( 2**24 + 2**8 + 2**7 ) | |||
| Experimentally, FNV_Primes matching the above constraints tend to | Experimentally, FNV_Primes matching the above constraints tend to | |||
| have better dispersion properties. They improve the polynomial | have better dispersion properties. They improve the polynomial | |||
| feedback characteristic when an FNV_Prime multiplies an intermediate | feedback characteristic when an FNV_Prime multiplies an intermediate | |||
| hash value. As such, the hash values produced are more scattered | hash value. As such, the hash values produced are more scattered | |||
| throughout the n-bit hash space. | throughout the n-bit hash space. | |||
| The case where s < 5 is not considered due to the resulting low hash | The case where s < 5 is not considered due to the resulting low hash | |||
| quality. Such small hashes can, if desired, be derived from a 32-bit | quality. Such small hashes can, if desired, be derived from a 32-bit | |||
| FNV hash by XOR folding (see Section 3). The case where s > 10 is | FNV hash by XOR folding (see Section 3). The case where s > 10 is | |||
| not considered because of the doubtful utility of such large FNV | not considered because of the doubtful utility of such large FNV | |||
| hashes and because the criteria for such large FNV_Primes is more | hashes and because the criteria for such large FNV_Primes would be | |||
| complex, due to the sparsity of such large primes, and would | more complex, due to the sparsity of such large primes, and would | |||
| needlessly clutter the criteria given above. | needlessly clutter the criteria given above. | |||
| Per the above constraints, an FNV_Prime should have only six or seven | Per the above constraints, an FNV_Prime should have only six or seven | |||
| one-bits in it: one relatively high-order one bit, the 2**9 bit, and | one bits in it: one relatively high-order one bit, the 2**9 bit, and | |||
| four or five one bits in the low-order byte. Therefore, some | four or five one bits in the low-order byte. Therefore, some | |||
| compilers may seek to improve the performance of a multiplication | compilers may seek to improve the performance of a multiplication | |||
| with an FNV_Prime by replacing the multiplication with shifts and | with an FNV_Prime by replacing the multiplication with shifts and | |||
| adds. However, the performance of this substitution is highly | adds. However, the performance of this substitution is highly | |||
| hardware dependent and should be done with care. The selection of | hardware dependent and should be done with care. The selection of | |||
| FNV_Primes prioritizes the quality of the resulting hash function, | FNV_Primes prioritizes the quality of the resulting hash function, | |||
| not compiler optimization considerations. | not compiler optimization considerations. | |||
| 2.2. FNV offset_basis | 2.2. FNV offset_basis | |||
| skipping to change at line 359 ¶ | skipping to change at line 359 ¶ | |||
| or, in C notation [C], the following string: | or, in C notation [C], the following string: | |||
| "chongo <Landon Curt Noll> /\\../\\" | "chongo <Landon Curt Noll> /\\../\\" | |||
| In the general case, almost any offset_basis would serve as long as | In the general case, almost any offset_basis would serve as long as | |||
| it is non-zero. However, FNV hashes calculated with different | it is non-zero. However, FNV hashes calculated with different | |||
| offset_basis values will not interoperate. The choice of a non- | offset_basis values will not interoperate. The choice of a non- | |||
| standard offset_basis may be beneficial in some limited circumstances | standard offset_basis may be beneficial in some limited circumstances | |||
| to defend against attacks that try to induce hash collisions as | to defend against attacks that try to induce hash collisions as | |||
| discussed in Section 6.1. Any entity that can observe the FNV hash | discussed in Section 6.1. Any entity that can observe the FNV hash | |||
| output, and can cause the null string (the string of length zero) to | output and can cause the null string (the string of length zero) to | |||
| be hashed, will thereby be able to directly observe the offset_basis | be hashed will thereby be able to directly observe the offset_basis | |||
| which will be the hash output. | which will be the hash output. | |||
| 2.3. FNV Endianism | 2.3. FNV Endianism | |||
| For persistent storage or interoperability between different hardware | For persistent storage or interoperability between different hardware | |||
| platforms, an FNV hash shall be represented in the little endian | platforms, an FNV hash shall be represented in the little-endian | |||
| format [IEN137]. That is, the FNV hash will be stored in an array | format [IEN137]. That is, the FNV hash will be stored in an array | |||
| hash[N] with N bytes such that its integer value can be retrieved as | hash[N] with N bytes such that its integer value can be retrieved as | |||
| follows: | follows: | |||
| unsigned char hash[N]; | unsigned char hash[N]; | |||
| for ( i = N-1, value = 0; i >= 0; --i ) | for ( i = N-1, value = 0; i >= 0; --i ) | |||
| value = ( value << 8 ) + hash[i]; | value = ( value << 8 ) + hash[i]; | |||
| However, when FNV hashes are used in a single process or a group of | However, when FNV hashes are used in a single process or a group of | |||
| processes sharing memory on processors with compatible endianness, | processes sharing memory on processors with compatible endianness, | |||
| the natural endianness of those processors can be used, as long as it | the natural endianness of those processors can be used, as long as it | |||
| is used consistently, regardless of its type -- little, big, or some | is used consistently, regardless of its type -- little, big, or some | |||
| other exotic form. | other exotic form. | |||
| The code provided in Section 6 has FNV hash functions that return a | The code provided in Section 8 has FNV hash functions that return a | |||
| little endian byte vector for all lengths. Because they are more | little-endian byte vector for all lengths. Because they are more | |||
| efficient, the code also provides functions that return FNV hashes as | efficient, the code also provides functions that return FNV hashes as | |||
| 32-bit integers or, where supported, 64-bit integers, for those sizes | 32-bit integers or, where supported, 64-bit integers, for those sizes | |||
| of FNV hash. Such integers are compatible with the same-size byte | of FNV hash. Such integers are compatible with the same-size byte | |||
| vectors on little endian computers, but the use of the functions | vectors on little-endian computers, but the use of the functions | |||
| returning integers on big endian or other non-little-endian machines | returning integers on big-endian or other non-little-endian machines | |||
| will be byte-reversed or otherwise incompatible with the byte vector | will be byte-reversed or otherwise incompatible with the byte vector | |||
| return values. | return values. | |||
| 3. Other Hash Sizes and XOR Folding | 3. Other Hash Sizes and XOR Folding | |||
| Many hash uses require a hash that is not one of the FNV sizes for | Many hash uses require a hash that is not one of the FNV sizes for | |||
| which constants are provided in Section 5. If a larger hash size is | which constants are provided in Section 5. If a larger hash size is | |||
| needed, please contact the authors of this document. | needed, please contact the authors of this document. | |||
| For scenarios where a fixed-size binary field of k bits is desired | For scenarios where a fixed-size binary field of k bits is desired | |||
| with k < 1024 but not among the constants provided in Section 5, the | with k < 1024 but not among the constants provided in Section 5, the | |||
| recommended approach involves using the smallest FNV hash of size S | recommended approach involves using the smallest FNV hash of size S | |||
| where S > k and employing xor folding, as shown below. The final | where S > k and employing XOR folding, as shown below. The final | |||
| bit-masking operation is logically unnecessary if the size of the | bit-masking operation is logically unnecessary if the size of the | |||
| variable k-bit-hash is exactly k bits. | variable k-bit-hash is exactly k bits. | |||
| temp = FNV_S ( data-to-be-hashed ) | temp = FNV_S ( data-to-be-hashed ) | |||
| k-bit-hash = ( temp xor temp>>k ) bitwise-and ( 2**k - 1 ) | k-bit-hash = ( temp XOR temp>>k ) bitwise-and ( 2**k - 1 ) | |||
| A somewhat stronger hash may be obtained for exact FNV sizes by | A somewhat stronger hash may be obtained for exact FNV sizes by | |||
| calculating an FNV twice as long as the desired output ( S = 2*k ) | calculating an FNV twice as long as the desired output ( S = 2*k ) | |||
| and performing such xor data folding using a k equal to the size of | and performing such XOR data folding using a k equal to the size of | |||
| the desired output. However, if a much stronger hash is desired, | the desired output. However, if a much stronger hash is desired, | |||
| cryptographic algorithms, such as those specified in [FIPS202] or | cryptographic algorithms, such as those specified in [FIPS202] or | |||
| [RFC6234], should be used. | [RFC6234], should be used. | |||
| If it is desired to obtain a hash result that is a value between 0 | If it is desired to obtain a hash result that is a value between 0 | |||
| and max, where max+1 is not a power of 2, simply choose an FNV hash | and max, where max+1 is not a power of 2, simply choose an FNV hash | |||
| size S such that 2**S > max. Then, calculate the following: | size S such that 2**S > max. Then, calculate the following: | |||
| FNV_S mod ( max+1 ) | FNV_S mod ( max+1 ) | |||
| skipping to change at line 449 ¶ | skipping to change at line 449 ¶ | |||
| where the vertical bar character ("|") represents string | where the vertical bar character ("|") represents string | |||
| concatenation. If the components being combined are of variable | concatenation. If the components being combined are of variable | |||
| length, some information is lost by simple concatenation. For | length, some information is lost by simple concatenation. For | |||
| example, X = "12" and Y = "345" would not be distinguished from X = | example, X = "12" and Y = "345" would not be distinguished from X = | |||
| "123" and Y = "45". To preserve that information, each component | "123" and Y = "45". To preserve that information, each component | |||
| should be preceded by an encoding of its length or should end with | should be preceded by an encoding of its length or should end with | |||
| some sequence that cannot occur within the component, or some similar | some sequence that cannot occur within the component, or some similar | |||
| technique should be used. | technique should be used. | |||
| For FNV, the same hash results if X, Y, and Z are actually | For FNV, the same hash results if 1) X, Y, and Z are actually | |||
| concatenated and the FNV hash applied to the resulting string or if | concatenated and the FNV hash is applied to the resulting string or | |||
| FNV is calculated on an initial substring and the result used as the | 2) FNV is calculated on an initial substring and the result is used | |||
| offset_basis when calculating the FNV hash of the remainder of the | as the offset_basis when calculating the FNV hash of the remainder of | |||
| string. This can be done several times. Assuming that | the string. This can be done several times. Assuming that | |||
| FNVoffset_basis ( v, w ) is the FNV of w using v as the offset_basis, | FNVoffset_basis ( v, w ) is the FNV of w using v as the offset_basis, | |||
| then in the example above, fnvx = FNV ( X ) could be calculated and | then in the example above, fnvx = FNV ( X ) could be calculated and | |||
| then fnvxy = FNVoffset_basis ( fnvx, Y ), and finally fnvxyz = | then fnvxy = FNVoffset_basis ( fnvx, Y ), and finally fnvxyz = | |||
| FNVoffset_basis ( fnvxy, Z ). The resulting fnvxyz would be the same | FNVoffset_basis ( fnvxy, Z ). The resulting fnvxyz would be the same | |||
| as FNV ( X | Y | Z ). | as FNV ( X | Y | Z ). | |||
| This means that if you have the value of FNV ( X ) and you want to | This means that if you have the value of FNV ( X ) and you want to | |||
| calculate FNV ( X | Y ), you do not need to find X. You can simply | calculate FNV ( X | Y ), you do not need to find X. You can simply | |||
| calculate FNVoffset_basis ( FNV ( X ), Y ) and thereby get FNV ( X | | calculate FNVoffset_basis ( FNV ( X ), Y ) and thereby get FNV ( X | | |||
| Y ). | Y ). | |||
| Sometimes, such a hash needs to be repeatedly calculated; the | Sometimes, such a hash needs to be repeatedly calculated; the | |||
| component values vary, but some vary more frequently than others. | component values vary, but some vary more frequently than others. | |||
| For example, assume that some sort of computer network traffic flow | For example, assume that some sort of computer network traffic flow | |||
| ID, such as the IPv6 flow ID [RFC6437], is to be calculated for | ID, such as the IPv6 Flow Label [RFC6437], is to be calculated for | |||
| network packets based on the source and destination IPv6 addresses | network packets based on the source and destination IPv6 addresses | |||
| and the Traffic Class [RFC8200]. If the Flow ID is calculated in the | and the Traffic Class [RFC8200]. If the Flow Label is calculated in | |||
| originating host, the source IPv6 address would likely always be the | the originating host, the source IPv6 address would likely always be | |||
| same or would perhaps assume one of a very small number of values. | the same or would perhaps assume one of a very small number of | |||
| By placing this quasi-constant IPv6 source address first in the | values. By placing this quasi-constant IPv6 source address first in | |||
| string being FNV-hashed, FNV ( IPv6source ) could be calculated and | the string being FNV-hashed, FNV ( IPv6source ) could be calculated | |||
| used as the offset_basis for calculating the FNV of the IPv6 | and used as the offset_basis for calculating the FNV of the IPv6 | |||
| destination address and Traffic Class for each packet. As a result, | destination address and Traffic Class for each packet. As a result, | |||
| the per-packet hash would be over 17 bytes rather than over 33 bytes, | the per-packet hash would be over 17 bytes rather than over 33 bytes, | |||
| saving computational resources. The source code in this document | saving computational resources. The source code in this document | |||
| includes functions facilitating the use of a non-standard | includes functions facilitating the use of a non-standard | |||
| offset_basis. | offset_basis. | |||
| An alternative method of hashing multiple values is to concatenate | An alternative method of hashing multiple values is to concatenate | |||
| the hashes of those values and then hash the concatenation -- that | the hashes of those values and then hash the concatenation -- that | |||
| is, compute something like | is, compute something like | |||
| skipping to change at line 774 ¶ | skipping to change at line 774 ¶ | |||
| replacing "xxx" with "64INT". Versions providing an integer hash | replacing "xxx" with "64INT". Versions providing an integer hash | |||
| will not be compatible between systems of different endianness (see | will not be compatible between systems of different endianness (see | |||
| Section 2.3). | Section 2.3). | |||
| If you want to copy the source code from this document, note that it | If you want to copy the source code from this document, note that it | |||
| is indented by three spaces in the ".txt" version. It may be | is indented by three spaces in the ".txt" version. It may be | |||
| simplest to copy from the ".html" version of this document. | simplest to copy from the ".html" version of this document. | |||
| FNVxxxstring, FNVxxxblock, FNVxxxfile: | FNVxxxstring, FNVxxxblock, FNVxxxfile: | |||
| FNVxxxstringBase, FNVxxxblockBase, FNVxxxfileBase: | FNVxxxstringBasis, FNVxxxblockBasis, FNVxxxfileBasis: | |||
| FNVxxxINTstring, FNVxxxINTblock, FNVxxxINTfile: | FNVxxxINTstring, FNVxxxINTblock, FNVxxxINTfile: | |||
| FNVxxxINTstringBase, FNVxxxINTblockBase, FNVxxxINTfileBase: These | FNVxxxINTstringBasis, FNVxxxINTblockBasis, FNVxxxINTfileBasis: These | |||
| are simple functions for directly returning the FNV hash of a | are simple functions for directly returning the FNV hash of a | |||
| zero-terminated byte string not including that zero byte, the FNV | zero-terminated byte string not including that zero byte, the FNV | |||
| hash of a counted block of bytes, and the FNV of a file, | hash of a counted block of bytes, and the FNV of a file, | |||
| respectively. The functions whose names have the "Base" suffix | respectively. The functions whose names have the "Basis" suffix | |||
| take an additional parameter specifying the offset_basis. Note | take an additional parameter specifying the offset_basis. Note | |||
| that for applications of FNV-32 and of FNV-64 where integers of | that for applications of FNV-32 and of FNV-64 where integers of | |||
| that size are supported and an integer data type output is | that size are supported and an integer data type output is | |||
| acceptable, the code is sufficiently simple that, to maximize | acceptable, the code is sufficiently simple that, to maximize | |||
| performance, the use of open coding or macros may be more | performance, the use of open coding or macros may be more | |||
| appropriate than calling a subroutine. | appropriate than calling a subroutine. | |||
| FNVxxxinit, FNVxxxinitBasis: | FNVxxxinit, FNVxxxinitBasis: | |||
| FNVxxxINTinitBasis: These functions and the next two sets of | FNVxxxINTinitBasis: These functions and the next two sets of | |||
| skipping to change at line 819 ¶ | skipping to change at line 819 ¶ | |||
| hash result from an FNVxxxcontext. | hash result from an FNVxxxcontext. | |||
| 8.1.2. Source Files and 64-Bit Support | 8.1.2. Source Files and 64-Bit Support | |||
| Code optimized for 64-bit integer support -- that is, support of | Code optimized for 64-bit integer support -- that is, support of | |||
| 64-bit integer addition and 32-bit x 32-bit multiplication producing | 64-bit integer addition and 32-bit x 32-bit multiplication producing | |||
| a 64-bit product -- is provided based on whether or not the | a 64-bit product -- is provided based on whether or not the | |||
| FNV_64bitIntegers symbol is defined. By default, this is set in | FNV_64bitIntegers symbol is defined. By default, this is set in | |||
| FNVconfig.h based on the compilation target; however, this can be | FNVconfig.h based on the compilation target; however, this can be | |||
| overridden by editing that file or by defining certain symbols in, | overridden by editing that file or by defining certain symbols in, | |||
| for example, a command line invoking compilation. | for example, a command line invoking a compilation. | |||
| For support of a single FNV size, say "xxx" (e.g., FNV64), in an | For support of a single FNV size, say "xxx" (e.g., FNV64), in an | |||
| application, the application itself needs to include the appropriate | application, the application itself needs to include the appropriate | |||
| FNVxxx.h file (which will, in turn, include the FNVconfig.h and | FNVxxx.h file (which will, in turn, include the FNVconfig.h and | |||
| FNVErrorCodes.h files). To build the particular FNVxxx code itself, | FNVErrorCodes.h files). To build the particular FNVxxx code itself, | |||
| compile the FNVxxx.c file with FNVconfig.h, fnv-private.h, | compile the FNVxxx.c file with FNVconfig.h, fnv-private.h, | |||
| FNVErrorCodes.h, and FNVxxx.h (available in Section 8.2). Since the | FNVErrorCodes.h, and FNVxxx.h (available to the compiler while | |||
| test program provided in Section 8.3 uses all sizes of FNV, all the | compiling the FNVxxx.c file; see Section 8.2). Since the test | |||
| .c and .h files are needed to compile it. | program provided in Section 8.3 uses all sizes of FNV, all the .c and | |||
| .h files are needed to compile it. | ||||
| 8.1.3. Command Line Interface | 8.1.3. Command Line Interface | |||
| The test program provided in Section 8.3 has a command line | The test program provided in Section 8.3 has a command line | |||
| interface. By default, with no command line arguments, it runs tests | interface. By default, with no command line arguments, it runs tests | |||
| of all FNV lengths. Command line options are as follows: | of all FNV lengths. Command line options are as follows: | |||
| FNVhash [-a] [-h] [-t nnn] [-u nnn] [-v] [-f filename] [token ...] | FNVhash [-a] [-h] [-t nnn] [-u nnn] [-v] [-f filename] [token ...] | |||
| The option letters have the following meanings: | The option letters have the following meanings: | |||
| skipping to change at line 1095 ¶ | skipping to change at line 1096 ¶ | |||
| int Computed; /* state */ | int Computed; /* state */ | |||
| uint32_t Hash; | uint32_t Hash; | |||
| } FNV32context; | } FNV32context; | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV32string: hash a zero-terminated string not including | * FNV32string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV32stringBasis: also takes an offset_basis parameter | * FNV32stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32block: hash a specified length byte vector | * FNV32block: hash a byte vector of a specified length | |||
| * FNV32blockBasis: also takes an offset_basis parameter | * FNV32blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32file: hash the contents of a file | * FNV32file: hash the contents of a file | |||
| * FNV32fileBasis: also takes an offset_basis parameter | * FNV32fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32init: initializes an FNV32 context | * FNV32init: initializes an FNV32 context | |||
| * FNV32initBasis: initializes an FNV32 context with a | * FNV32initBasis: initializes an FNV32 context with a | |||
| * provided 4-byte vector basis | * provided 4-byte vector basis | |||
| * FNV32blockin: hash in a specified length byte vector | * FNV32blockin: hash in a byte vector of a specified length | |||
| * FNV32stringin: hash in a zero-terminated string not | * FNV32stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV32filein: hash in the contents of a file | * FNV32filein: hash in the contents of a file | |||
| * FNV32result: returns the hash value | * FNV32result: returns the hash value | |||
| * | * | |||
| * Hash is returned as a 4-byte vector by the functions above, | * Hash is returned as a 4-byte vector by the functions above, | |||
| * and the following return a 32-bit unsigned integer: | * and the following return a 32-bit unsigned integer: | |||
| * | * | |||
| * FNV32INTstring: hash a zero-terminated string not including | * FNV32INTstring: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV32INTstringBasis: also takes an offset_basis parameter | * FNV32INTstringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32INTblock: hash a specified length byte vector | * FNV32INTblock: hash a byte vector of a specified length | |||
| * FNV32INTblockBasis: also takes an offset_basis parameter | * FNV32INTblockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32INTfile: hash the contents of a file | * FNV32INTfile: hash the contents of a file | |||
| * FNV32INTfileBasis: also takes an offset_basis parameter | * FNV32INTfileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV32INTinitBasis: initializes an FNV32 context with a | * FNV32INTinitBasis: initializes an FNV32 context with a | |||
| * provided 32-bit integer basis | * provided 32-bit integer basis | |||
| * FNV32INTresult: returns the hash value | * FNV32INTresult: returns the hash value | |||
| */ | */ | |||
| skipping to change at line 1211 ¶ | skipping to change at line 1212 ¶ | |||
| */ | */ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV32.h" | #include "FNV32.h" | |||
| /* 32-bit FNV_prime = 2^24 + 2^8 + 0x93 */ | /* 32-bit FNV_prime = 2^24 + 2^8 + 0x93 */ | |||
| #define FNV32prime 0x01000193 | #define FNV32prime 0x01000193 | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32: hash a zero-terminated string not including the zero | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32INTstring ( const char *in, uint32_t * const out ) { | int FNV32INTstring ( const char *in, uint32_t * const out ) { | |||
| return FNV32INTstringBasis ( in, out, FNV32basis ); | return FNV32INTstringBasis ( in, out, FNV32basis ); | |||
| } /* end FNV32INTstring */ | } /* end FNV32INTstring */ | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32: hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32INTstringBasis ( const char *in, | int FNV32INTstringBasis ( const char *in, | |||
| uint32_t * const out, | uint32_t * const out, | |||
| uint32_t basis ) { | uint32_t basis ) { | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| basis = FNV32prime * ( basis ^ ch ); | basis = FNV32prime * ( basis ^ ch ); | |||
| *out = basis; | *out = basis; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32INTstringBasis */ | } /* end FNV32INTstringBasis */ | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32: hash a zero-terminated string not including the zero | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32string ( const char *in, uint8_t out[FNV32size] ) { | int FNV32string ( const char *in, uint8_t out[FNV32size] ) { | |||
| uint32_t temp; | uint32_t temp; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| temp = FNV32basis; | temp = FNV32basis; | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| temp = FNV32prime * ( temp ^ ch ); | temp = FNV32prime * ( temp ^ ch ); | |||
| for ( int i=0; i<FNV32size; ++i ) | for ( int i=0; i<FNV32size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32string */ | } /* end FNV32string */ | |||
| /* FNV32 hash a zero-terminated string not including the zero | /* FNV32: hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV32stringBasis ( const char *in, | int FNV32stringBasis ( const char *in, | |||
| uint8_t out[FNV32size], | uint8_t out[FNV32size], | |||
| const uint8_t basis[FNV32size] ) { | const uint8_t basis[FNV32size] ) { | |||
| uint32_t temp; | uint32_t temp; | |||
| int i; | int i; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out || !basis ) | if ( !in || !out || !basis ) | |||
| skipping to change at line 1272 ¶ | skipping to change at line 1273 ¶ | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| temp = FNV32prime * ( temp ^ ch ); | temp = FNV32prime * ( temp ^ ch ); | |||
| out[0] = temp & 0xFF; | out[0] = temp & 0xFF; | |||
| for ( i=1; i<FNV32size; ++i ) { | for ( i=1; i<FNV32size; ++i ) { | |||
| temp >>= 8; | temp >>= 8; | |||
| out[i] = temp & 0xFF; | out[i] = temp & 0xFF; | |||
| } | } | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32stringBasis */ | } /* end FNV32stringBasis */ | |||
| /* FNV32 hash a counted block returning an integer | /* FNV32: hash a counted block returning an integer | |||
| ****************************************************************/ | ****************************************************************/ | |||
| int FNV32INTblock ( const void *vin, | int FNV32INTblock ( const void *vin, | |||
| long int length, | long int length, | |||
| uint32_t * const out ) { | uint32_t * const out ) { | |||
| return FNV32INTblockBasis ( vin, length, out, FNV32basis ); | return FNV32INTblockBasis ( vin, length, out, FNV32basis ); | |||
| } /* end FNV32INTblock */ | } /* end FNV32INTblock */ | |||
| /* FNV32 hash a counted block with a non-standard basis | /* FNV32: hash a counted block with a non-standard basis | |||
| ****************************************************************/ | ****************************************************************/ | |||
| int FNV32INTblockBasis ( const void *vin, | int FNV32INTblockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint32_t * const out, | uint32_t * const out, | |||
| uint32_t basis ) { | uint32_t basis ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint32_t temp; | uint32_t temp; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| if ( length < 0 ) | if ( length < 0 ) | |||
| return fnvBadParam; | return fnvBadParam; | |||
| for ( temp = basis; length > 0; length-- ) | for ( temp = basis; length > 0; length-- ) | |||
| temp = FNV32prime * ( temp ^ *in++ ); | temp = FNV32prime * ( temp ^ *in++ ); | |||
| *out = temp; | *out = temp; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32INTblockBasis */ | } /* end FNV32INTblockBasis */ | |||
| /* FNV32 hash a counted block returning a 4-byte vector | /* FNV32: hash a counted block returning a 4-byte vector | |||
| ****************************************************************/ | ****************************************************************/ | |||
| int FNV32block ( const void *vin, | int FNV32block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV32size] ) { | uint8_t out[FNV32size] ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint32_t temp; | uint32_t temp; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| if ( length < 0 ) | if ( length < 0 ) | |||
| return fnvBadParam; | return fnvBadParam; | |||
| for ( temp = FNV32basis; length > 0; length-- ) | for ( temp = FNV32basis; length > 0; length-- ) | |||
| temp = FNV32prime * ( temp ^ *in++ ); | temp = FNV32prime * ( temp ^ *in++ ); | |||
| for ( int i=0; i<FNV32size; ++i ) | for ( int i=0; i<FNV32size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV32block */ | } /* end FNV32block */ | |||
| /* FNV32 hash a counted block with a non-standard basis | /* FNV32: hash a counted block with a non-standard basis | |||
| ****************************************************************/ | ****************************************************************/ | |||
| int FNV32blockBasis ( const void *vin, | int FNV32blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV32size], | uint8_t out[FNV32size], | |||
| const uint8_t basis[FNV32size] ) { | const uint8_t basis[FNV32size] ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint32_t temp; | uint32_t temp; | |||
| if ( !in || !out || !basis ) | if ( !in || !out || !basis ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| skipping to change at line 1617 ¶ | skipping to change at line 1618 ¶ | |||
| } FNV64context; | } FNV64context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV64string: hash a zero-terminated string not including | * FNV64string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV64stringBasis: also takes an offset_basis parameter | * FNV64stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64block: hash a specified length byte vector | * FNV64block: hash a byte vector of a specified length | |||
| * FNV64blockBasis: also takes an offset_basis parameter | * FNV64blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64file: hash the contents of a file | * FNV64file: hash the contents of a file | |||
| * FNV128fileBasis: also takes an offset_basis parameter | * FNV64fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64init: initializes an FNV64 context | * FNV64init: initializes an FNV64 context | |||
| * FNV64initBasis: initializes an FNV64 context with a | * FNV64initBasis: initializes an FNV64 context with a | |||
| * provided 8-byte vector basis | * provided 8-byte vector basis | |||
| * FNV64blockin: hash in a specified length byte vector | * FNV64blockin: hash in a byte vector of a specified length | |||
| * FNV64stringin: hash in a zero-terminated string not | * FNV64stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV128filein: hash in the contents of a file | * FNV64filein: hash in the contents of a file | |||
| * FNV64result: returns the hash value | * FNV64result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an 8-byte vector by the functions above. | * Hash is returned as an 8-byte vector by the functions above. | |||
| * If 64-bit integers are supported, the following return | * If 64-bit integers are supported, the following return | |||
| * a 64-bit integer. | * a 64-bit integer. | |||
| * | * | |||
| * FNV64INTstring: hash a zero-terminated string not including | * FNV64INTstring: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV32INTstringBasis: also takes an offset_basis parameter | * FNV64INTstringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64INTblock: hash a specified length byte vector | * FNV64INTblock: hash a byte vector of a specified length | |||
| * FNV32INTblockBasis: also takes an offset_basis parameter | * FNV64INTblockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64INTfile: hash the contents of a file | * FNV64INTfile: hash the contents of a file | |||
| * FNV32INTfileBasis: also takes an offset_basis parameter | * FNV64INTfileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV64INTinitBasis: initializes an FNV32 context with a | * FNV64INTinitBasis: initializes an FNV64 context with a | |||
| * provided 64-bit integer basis | * provided 64-bit integer basis | |||
| * FNV64INTresult: returns the hash value | * FNV64INTresult: returns the hash value | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| #endif | #endif | |||
| /* FNV64 */ | /* FNV64 */ | |||
| extern int FNV64string ( const char *in, | extern int FNV64string ( const char *in, | |||
| skipping to change at line 1819 ¶ | skipping to change at line 1820 ¶ | |||
| } | } | |||
| //***************************************************************** | //***************************************************************** | |||
| // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // START VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //***************************************************************** | //***************************************************************** | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | |||
| #define FNV64prime 0x00000100000001B3 | #define FNV64prime 0x00000100000001B3 | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64: hash a zero-terminated string not including the zero | |||
| * to a 64-bit integer (64-bit) | * to a 64-bit integer (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTstring ( const char *in, uint64_t * const out ) { | int FNV64INTstring ( const char *in, uint64_t * const out ) { | |||
| return FNV64INTstringBasis ( in, out, FNV64basis ); | return FNV64INTstringBasis ( in, out, FNV64basis ); | |||
| } /* end FNV64INTstring */ | } /* end FNV64INTstring */ | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64: hash a zero-terminated string not including the zero | |||
| * to a 64-bit integer (64-bit) with a non-standard basis | * to a 64-bit integer (64-bit) with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTstringBasis ( const char *in, | int FNV64INTstringBasis ( const char *in, | |||
| uint64_t * const out, | uint64_t * const out, | |||
| uint64_t basis ) { | uint64_t basis ) { | |||
| uint64_t temp; | uint64_t temp; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| temp = basis; | temp = basis; | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| temp = FNV64prime * ( temp ^ ch ); | temp = FNV64prime * ( temp ^ ch ); | |||
| *out = temp; | *out = temp; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64INTstringBasis */ | } /* end FNV64INTstringBasis */ | |||
| /* FNV64 hash a zero-terminated string to a 64-bit integer | /* FNV64: hash a zero-terminated string to a 64-bit integer | |||
| * to a byte vector (64-bit) | * to a byte vector (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | |||
| uint64_t temp; | uint64_t temp; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input pointer */ | return fnvNull; /* Null input pointer */ | |||
| temp = FNV64basis; | temp = FNV64basis; | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| temp = FNV64prime * ( temp ^ ch ); | temp = FNV64prime * ( temp ^ ch ); | |||
| for ( int i=0; i<FNV64size; ++i ) | for ( int i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64string */ | } /* end FNV64string */ | |||
| /* FNV64 hash a zero-terminated string to a 64-bit integer | /* FNV64: hash a zero-terminated string to a 64-bit integer | |||
| * to a byte vector (64-bit) with a non-standard basis | * to a byte vector (64-bit) with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64stringBasis ( const char *in, | int FNV64stringBasis ( const char *in, | |||
| uint8_t out[FNV64size], | uint8_t out[FNV64size], | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| uint64_t temp; | uint64_t temp; | |||
| int i; | int i; | |||
| uint8_t ch; | uint8_t ch; | |||
| if ( !in || !out || !basis ) | if ( !in || !out || !basis ) | |||
| skipping to change at line 1883 ¶ | skipping to change at line 1884 ¶ | |||
| temp = basis[7]; | temp = basis[7]; | |||
| for ( i = FNV64size-2; i>=0; --i ) | for ( i = FNV64size-2; i>=0; --i ) | |||
| temp = (temp<<8) + basis[i]; | temp = (temp<<8) + basis[i]; | |||
| while ( (ch = *in++) ) | while ( (ch = *in++) ) | |||
| temp = FNV64prime * ( temp ^ ch ); | temp = FNV64prime * ( temp ^ ch ); | |||
| for ( i=0; i<FNV64size; ++i ) | for ( i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64stringBasis */ | } /* end FNV64stringBasis */ | |||
| /* FNV64 hash a counted block to a 64-bit integer (64-bit) | /* FNV64: hash a counted block to a 64-bit integer (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTblock ( const void *vin, | int FNV64INTblock ( const void *vin, | |||
| long int length, | long int length, | |||
| uint64_t * const out ) { | uint64_t * const out ) { | |||
| return FNV64INTblockBasis ( vin, length, out, FNV64basis ); | return FNV64INTblockBasis ( vin, length, out, FNV64basis ); | |||
| } /* end FNV64INTblock */ | } /* end FNV64INTblock */ | |||
| /* FNV64 hash a counted block to a 64-bit integer (64-bit) | /* FNV64: hash a counted block to a 64-bit integer (64-bit) | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64INTblockBasis ( const void *vin, | int FNV64INTblockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint64_t * const out, | uint64_t * const out, | |||
| uint64_t basis ) { | uint64_t basis ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint64_t temp; | uint64_t temp; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input/out pointer */ | return fnvNull; | |||
| /* Null input pointer or null output pointer */ | ||||
| if ( length < 0 ) | if ( length < 0 ) | |||
| return fnvBadParam; | return fnvBadParam; | |||
| for ( temp = basis; length > 0; length-- ) | for ( temp = basis; length > 0; length-- ) | |||
| temp = FNV64prime * ( temp ^ *in++ ); | temp = FNV64prime * ( temp ^ *in++ ); | |||
| *out = temp; | *out = temp; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64INTblockBasis */ | } /* end FNV64INTblockBasis */ | |||
| /* FNV64 hash a counted block to a byte vector (64-bit) | /* FNV64: hash a counted block to a byte vector (64-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64block ( const void *vin, | int FNV64block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV64size] ) { | uint8_t out[FNV64size] ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint64_t temp; | uint64_t temp; | |||
| if ( !in || !out ) | if ( !in || !out ) | |||
| return fnvNull; /* Null input/out pointer */ | return fnvNull; | |||
| /* Null input pointer or null output pointer */ | ||||
| if ( length < 0 ) | if ( length < 0 ) | |||
| return fnvBadParam; | return fnvBadParam; | |||
| for ( temp = FNV64basis; length > 0; length-- ) | for ( temp = FNV64basis; length > 0; length-- ) | |||
| temp = FNV64prime * ( temp ^ *in++ ); | temp = FNV64prime * ( temp ^ *in++ ); | |||
| for ( int i=0; i<FNV64size; ++i ) | for ( int i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64block */ | } /* end FNV64block */ | |||
| /* FNV64 hash a counted block to a byte vector (64-bit) | /* FNV64: hash a counted block to a byte vector (64-bit) | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64blockBasis ( const void *vin, | int FNV64blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV64size], | uint8_t out[FNV64size], | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| const uint8_t *in = (const uint8_t*)vin; | const uint8_t *in = (const uint8_t*)vin; | |||
| uint64_t temp; | uint64_t temp; | |||
| int i; | int i; | |||
| if ( !in || !out || !basis ) | if ( !in || !out || !basis ) | |||
| return fnvNull; /* Null input/out pointer */ | return fnvNull; | |||
| /* Null input pointer or null output pointer */ | ||||
| if ( length < 0 ) | if ( length < 0 ) | |||
| return fnvBadParam; | return fnvBadParam; | |||
| temp = basis[7]; | temp = basis[7]; | |||
| for ( i = FNV64size-2; i>=0; --i ) | for ( i = FNV64size-2; i>=0; --i ) | |||
| temp = (temp<<8) + basis[i]; | temp = (temp<<8) + basis[i]; | |||
| for (; length > 0; length-- ) | for (; length > 0; length-- ) | |||
| temp = FNV64prime * ( temp ^ *in++ ); | temp = FNV64prime * ( temp ^ *in++ ); | |||
| for ( i=0; i<FNV64size; ++i ) | for ( i=0; i<FNV64size; ++i ) | |||
| out[i] = ((uint8_t *)&temp)[i]; | out[i] = ((uint8_t *)&temp)[i]; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| skipping to change at line 2115 ¶ | skipping to change at line 2119 ¶ | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //*************************************************************** | //*************************************************************** | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //*************************************************************** | //*************************************************************** | |||
| /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | /* 64-bit FNV_prime = 2^40 + 2^8 + 0xb3 */ | |||
| /* #define FNV64prime 0x00000100000001B3 */ | /* #define FNV64prime 0x00000100000001B3 */ | |||
| #define FNV64primeX 0x01B3 | #define FNV64primeX 0x01B3 | |||
| #define FNV64shift 8 | #define FNV64shift 8 | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | int FNV64string ( const char *in, uint8_t out[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64init (&ctx)) ) | if ( (error = FNV64init (&ctx)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV64stringin (&ctx, in)) ) | if ( (error = FNV64stringin (&ctx, in)) ) | |||
| return error; | return error; | |||
| return FNV64result (&ctx, out); | return FNV64result (&ctx, out); | |||
| } /* end FNV64string */ | } /* end FNV64string */ | |||
| /* FNV64 hash a zero-terminated string not including the zero | /* FNV64: hash a zero-terminated string not including the zero | |||
| * with a non-standard offset_basis | * with a non-standard offset_basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64stringBasis ( const char *in, | int FNV64stringBasis ( const char *in, | |||
| uint8_t out[FNV64size], | uint8_t out[FNV64size], | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64initBasis (&ctx, basis)) ) | if ( (error = FNV64initBasis (&ctx, basis)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV64stringin (&ctx, in)) ) | if ( (error = FNV64stringin (&ctx, in)) ) | |||
| return error; | return error; | |||
| return FNV64result (&ctx, out); | return FNV64result (&ctx, out); | |||
| } /* end FNV64stringBasis */ | } /* end FNV64stringBasis */ | |||
| /* FNV64 hash a counted block | /* FNV64: hash a counted block | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64block ( const void *vin, | int FNV64block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV64size] ) { | uint8_t out[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64init (&ctx)) ) | if ( (error = FNV64init (&ctx)) ) | |||
| return error; | return error; | |||
| if ( (error = FNV64blockin (&ctx, vin, length)) ) | if ( (error = FNV64blockin (&ctx, vin, length)) ) | |||
| return error; | return error; | |||
| return FNV64result (&ctx, out); | return FNV64result (&ctx, out); | |||
| } /* end FNV64block */ | } /* end FNV64block */ | |||
| /* FNV64 hash a counted block with a non-standard offset_basis | /* FNV64: hash a counted block with a non-standard offset_basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64blockBasis ( const void *vin, | int FNV64blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV64size], | uint8_t out[FNV64size], | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| FNV64context ctx; | FNV64context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV64initBasis (&ctx, basis)) ) | if ( (error = FNV64initBasis (&ctx, basis)) ) | |||
| return error; | return error; | |||
| skipping to change at line 2201 ¶ | skipping to change at line 2205 ¶ | |||
| } /* end FNV64init */ | } /* end FNV64init */ | |||
| /* initialize context with a non-standard basis (32-bit) | /* initialize context with a non-standard basis (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64initBasis ( FNV64context * const ctx, | int FNV64initBasis ( FNV64context * const ctx, | |||
| const uint8_t basis[FNV64size] ) { | const uint8_t basis[FNV64size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV64size/2; ++i ) { | for ( int i=0; i < FNV64size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV64state; | ctx->Computed = FNVinited+FNV64state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV64initBasis */ | } /* end FNV64initBasis */ | |||
| /* hash in a counted block (32-bit) | /* hash in a counted block (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV64blockin ( FNV64context * const ctx, | int FNV64blockin ( FNV64context * const ctx, | |||
| const void *vin, | const void *vin, | |||
| long int length ) { | long int length ) { | |||
| skipping to change at line 2377 ¶ | skipping to change at line 2381 ¶ | |||
| } FNV128context; | } FNV128context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV128string: hash a zero-terminated string not including | * FNV128string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV128stringBasis: also takes an offset_basis parameter | * FNV128stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV128block: hash a specified length byte vector | * FNV128block: hash a byte vector of a specified length | |||
| * FNV128blockBasis: also takes an offset_basis parameter | * FNV128blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV128file: hash the contents of a file | * FNV128file: hash the contents of a file | |||
| * FNV128fileBasis: also takes an offset_basis parameter | * FNV128fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV128init: initializes an FNV128 context | * FNV128init: initializes an FNV128 context | |||
| * FNV128initBasis: initializes an FNV128 context with a | * FNV128initBasis: initializes an FNV128 context with a | |||
| * provided 16-byte vector basis | * provided 16-byte vector basis | |||
| * FNV128blockin: hash in a specified length byte vector | * FNV128blockin: hash in a byte vector of a specified length | |||
| * FNV128stringin: hash in a zero-terminated string not | * FNV128stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV128filein: hash in the contents of a file | * FNV128filein: hash in the contents of a file | |||
| * FNV128result: returns the hash value | * FNV128result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| skipping to change at line 2459 ¶ | skipping to change at line 2463 ¶ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "FNVconfig.h" | #include "FNVconfig.h" | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV128.h" | #include "FNV128.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| //***************************************************************** | //***************************************************************** | |||
| /* FNV128 hash a zero-terminated string not including the zero | /* FNV128: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128string ( const char *in, uint8_t out[FNV128size] ) { | int FNV128string ( const char *in, uint8_t out[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128init ( &ctx )) ) | if ( (error = FNV128init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV128stringin ( &ctx, in )) ) | if ( (error = FNV128stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV128result (&ctx, out); | return FNV128result (&ctx, out); | |||
| } /* end FNV128string */ | } /* end FNV128string */ | |||
| /* FNV128 hash a zero-terminated string not including the zero | /* FNV128: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128stringBasis ( const char *in, | int FNV128stringBasis ( const char *in, | |||
| uint8_t out[FNV128size], | uint8_t out[FNV128size], | |||
| const uint8_t basis[FNV128size] ) { | const uint8_t basis[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128initBasis ( &ctx, basis )) ) | if ( (error = FNV128initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV128stringin ( &ctx, in )) ) | if ( (error = FNV128stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV128result ( &ctx, out ); | return FNV128result ( &ctx, out ); | |||
| } /* end FNV128stringBasis */ | } /* end FNV128stringBasis */ | |||
| /* FNV128 hash a counted block (64/32-bit) | /* FNV128: hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128block ( const void *vin, | int FNV128block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV128size] ) { | uint8_t out[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128init ( &ctx )) ) | if ( (error = FNV128init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV128blockin ( &ctx, vin, length )) ) | if ( (error = FNV128blockin ( &ctx, vin, length )) ) | |||
| return error; | return error; | |||
| return FNV128result ( &ctx, out ); | return FNV128result ( &ctx, out ); | |||
| } /* end FNV128block */ | } /* end FNV128block */ | |||
| /* FNV128 hash a counted block (64/32-bit) | /* FNV128: hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128blockBasis ( const void *vin, | int FNV128blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV128size], | uint8_t out[FNV128size], | |||
| const uint8_t basis[FNV128size] ) { | const uint8_t basis[FNV128size] ) { | |||
| FNV128context ctx; | FNV128context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV128initBasis ( &ctx, basis )) ) | if ( (error = FNV128initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| skipping to change at line 2777 ¶ | skipping to change at line 2781 ¶ | |||
| } /* end FNV128init */ | } /* end FNV128init */ | |||
| /* initialize context with a provided 16-byte vector basis (32-bit) | /* initialize context with a provided 16-byte vector basis (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV128initBasis ( FNV128context * const ctx, | int FNV128initBasis ( FNV128context * const ctx, | |||
| const uint8_t basis[FNV128size] ) { | const uint8_t basis[FNV128size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV128size/2; ++i ) { | for ( int i=0; i < FNV128size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV128state; | ctx->Computed = FNVinited+FNV128state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV128initBasis */ | } /* end FNV128initBasis */ | |||
| /* hash in a counted block (32-bit) | /* hash in a counted block (32-bit) | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV128blockin ( FNV128context * const ctx, | int FNV128blockin ( FNV128context * const ctx, | |||
| const void *vin, | const void *vin, | |||
| long int length ) { | long int length ) { | |||
| skipping to change at line 2953 ¶ | skipping to change at line 2957 ¶ | |||
| } FNV256context; | } FNV256context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV256string: hash a zero-terminated string not including | * FNV256string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV256stringBasis: also takes an offset_basis parameter | * FNV256stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256block: hash a specified length byte vector | * FNV256block: hash a byte vector of a specified length | |||
| * FNV256blockBasis: also takes an offset_basis parameter | * FNV256blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256file: hash the contents of a file | * FNV256file: hash the contents of a file | |||
| * FNV256fileBasis: also takes an offset_basis parameter | * FNV256fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV256init: initializes an FNV256 context | * FNV256init: initializes an FNV256 context | |||
| * FNV256initBasis: initializes an FNV256 context with a | * FNV256initBasis: initializes an FNV256 context with a | |||
| * provided 32-byte vector basis | * provided 32-byte vector basis | |||
| * FNV256blockin: hash in a specified length byte vector | * FNV256blockin: hash in a byte vector of a specified length | |||
| * FNV256stringin: hash in a zero-terminated string not | * FNV256stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV256filein: hash in the contents of a file | * FNV256filein: hash in the contents of a file | |||
| * FNV256result: returns the hash value | * FNV256result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| skipping to change at line 3034 ¶ | skipping to change at line 3038 ¶ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV256.h" | #include "FNV256.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| //***************************************************************** | //***************************************************************** | |||
| /* FNV256 hash a zero-terminated string not including the zero | /* FNV256: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV256string ( const char *in, uint8_t out[FNV256size] ) { | int FNV256string ( const char *in, uint8_t out[FNV256size] ) { | |||
| FNV256context ctx; | FNV256context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV256init ( &ctx )) ) | if ( (error = FNV256init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV256stringin ( &ctx, in )) ) | if ( (error = FNV256stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV256result ( &ctx, out ); | return FNV256result ( &ctx, out ); | |||
| } /* end FNV256string */ | } /* end FNV256string */ | |||
| /* FNV256 hash a zero-terminated string not including the zero | /* FNV256: hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV256stringBasis ( const char *in, | int FNV256stringBasis ( const char *in, | |||
| uint8_t out[FNV256size], | uint8_t out[FNV256size], | |||
| const uint8_t basis[FNV256size] ) { | const uint8_t basis[FNV256size] ) { | |||
| FNV256context ctx; | FNV256context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV256initBasis ( &ctx, basis )) ) | if ( (error = FNV256initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV256stringin ( &ctx, in )) ) | if ( (error = FNV256stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV256result ( &ctx, out ); | return FNV256result ( &ctx, out ); | |||
| } /* end FNV256stringBasis */ | } /* end FNV256stringBasis */ | |||
| /* FNV256 hash a counted block (64/32-bit) | /* FNV256: hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV256block ( const void *vin, | int FNV256block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV256size] ) { | uint8_t out[FNV256size] ) { | |||
| FNV256context ctx; | FNV256context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV256init ( &ctx )) ) | if ( (error = FNV256init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV256blockin ( &ctx, vin, length)) ) | if ( (error = FNV256blockin ( &ctx, vin, length)) ) | |||
| return error; | return error; | |||
| return FNV256result ( &ctx, out ); | return FNV256result ( &ctx, out ); | |||
| } /* end FNV256block */ | } /* end FNV256block */ | |||
| /* FNV256 hash a counted block (64/32-bit) | /* FNV256: hash a counted block (64/32-bit) | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV256blockBasis ( const void *vin, | int FNV256blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV256size], | uint8_t out[FNV256size], | |||
| const uint8_t basis[FNV256size] ) { | const uint8_t basis[FNV256size] ) { | |||
| FNV256context ctx; | FNV256context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV256initBasis ( &ctx, basis )) ) | if ( (error = FNV256initBasis ( &ctx, basis )) ) | |||
| skipping to change at line 3324 ¶ | skipping to change at line 3328 ¶ | |||
| } /* end FNV256result */ | } /* end FNV256result */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //**************************************************************** | //**************************************************************** | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //**************************************************************** | //**************************************************************** | |||
| /* version for when you only have 32-bit arithmetic | ||||
| *****************************************************************/ | ||||
| /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | /* 256-bit FNV_prime = 2^168 + 2^8 + 0x63 */ | |||
| /* 0x00000000 00000000 00000100 00000000 | /* 0x00000000 00000000 00000100 00000000 | |||
| 00000000 00000000 00000000 00000163 */ | 00000000 00000000 00000000 00000163 */ | |||
| #define FNV256primeX 0x0163 | #define FNV256primeX 0x0163 | |||
| #define FNV256shift 8 | #define FNV256shift 8 | |||
| //**************************************************************** | //**************************************************************** | |||
| // Set of init, input, and output functions below | // Set of init, input, and output functions below | |||
| // to incrementally compute FNV256 | // to incrementally compute FNV256 | |||
| //**************************************************************** | //**************************************************************** | |||
| skipping to change at line 3361 ¶ | skipping to change at line 3362 ¶ | |||
| } /* end FNV256init */ | } /* end FNV256init */ | |||
| /* initialize context with a provided 32-byte vector basis (32-bit) | /* initialize context with a provided 32-byte vector basis (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV256initBasis ( FNV256context * const ctx, | int FNV256initBasis ( FNV256context * const ctx, | |||
| const uint8_t basis[FNV256size] ) { | const uint8_t basis[FNV256size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV256size/2; ++i ) { | for ( int i=0; i < FNV256size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + (*basis++); | ctx->Hash[i] = ( temp<<8 ) + (*basis++); | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV256state; | ctx->Computed = FNVinited+FNV256state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV256initBasis */ | } /* end FNV256initBasis */ | |||
| /* hash in a counted block (32-bit) | /* hash in a counted block (32-bit) | |||
| *****************************************************************/ | *****************************************************************/ | |||
| int FNV256blockin ( FNV256context * const ctx, | int FNV256blockin ( FNV256context * const ctx, | |||
| const void *vin, | const void *vin, | |||
| long int length ) { | long int length ) { | |||
| skipping to change at line 3537 ¶ | skipping to change at line 3538 ¶ | |||
| } FNV512context; | } FNV512context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV512string: hash a zero-terminated string not including | * FNV512string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV512stringBasis: also takes an offset_basis parameter | * FNV512stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512block: hash a specified length byte vector | * FNV512block: hash a byte vector of a specified length | |||
| * FNV512blockBasis: also takes an offset_basis parameter | * FNV512blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512file: hash the contents of a file | * FNV512file: hash the contents of a file | |||
| * FNV512fileBasis: also takes an offset_basis parameter | * FNV512fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV512init: initializes an FNV1024 context | * FNV512init: initializes an FNV512 context | |||
| * FNV512initBasis: initializes an FNV1024 context with a | * FNV512initBasis: initializes an FNV512 context with a | |||
| * provided 128-byte vector basis | * provided 64-byte vector basis | |||
| * FNV512blockin: hash in a specified length byte vector | * FNV512blockin: hash in a byte vector of a specified length | |||
| * FNV512stringin: hash in a zero-terminated string not | * FNV512stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV512filein: hash in the contents of a file | * FNV512filein: hash in the contents of a file | |||
| * FNV512result: returns the hash value | * FNV512result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| skipping to change at line 3618 ¶ | skipping to change at line 3619 ¶ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV512.h" | #include "FNV512.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| //***************************************************************** | //***************************************************************** | |||
| /* FNV512 hash a zero-terminated string not including the zero | /* FNV512: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512string ( const char *in, uint8_t out[FNV512size] ) { | int FNV512string ( const char *in, uint8_t out[FNV512size] ) { | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512init ( &ctx )) ) | if ( (error = FNV512init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV512stringin ( &ctx, in )) ) | if ( (error = FNV512stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV512result ( &ctx, out ); | return FNV512result ( &ctx, out ); | |||
| } /* end FNV512string */ | } /* end FNV512string */ | |||
| /* FNV512 hash a zero-terminated string not including the zero | /* FNV512: hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512stringBasis ( const char *in, | int FNV512stringBasis ( const char *in, | |||
| uint8_t out[FNV512size], | uint8_t out[FNV512size], | |||
| const uint8_t basis[FNV512size] ) { | const uint8_t basis[FNV512size] ) { | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512initBasis ( &ctx, basis )) ) | if ( (error = FNV512initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV512stringin ( &ctx, in )) ) | if ( (error = FNV512stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV512result ( &ctx, out ); | return FNV512result ( &ctx, out ); | |||
| } /* end FNV512stringBasis */ | } /* end FNV512stringBasis */ | |||
| /* FNV512 hash a counted block (64/32-bit) | /* FNV512: hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512block ( const void *vin, | int FNV512block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV512size] ) { | uint8_t out[FNV512size] ) { | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512init ( &ctx )) ) | if ( (error = FNV512init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV512blockin ( &ctx, vin, length)) ) | if ( (error = FNV512blockin ( &ctx, vin, length)) ) | |||
| return error; | return error; | |||
| return FNV512result ( &ctx, out ); | return FNV512result ( &ctx, out ); | |||
| } /* end FNV512block */ | } /* end FNV512block */ | |||
| /* FNV512 hash a counted block (64/32-bit) | /* FNV512: hash a counted block (64/32-bit) | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512blockBasis ( const void *vin, | int FNV512blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV512size], | uint8_t out[FNV512size], | |||
| const uint8_t basis[FNV512size] ) { | const uint8_t basis[FNV512size] ) { | |||
| FNV512context ctx; | FNV512context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV512initBasis ( &ctx, basis )) ) | if ( (error = FNV512initBasis ( &ctx, basis )) ) | |||
| skipping to change at line 3949 ¶ | skipping to change at line 3950 ¶ | |||
| } /* end FNV512init */ | } /* end FNV512init */ | |||
| /* initialize context with a provided 64-byte vector basis (32-bit) | /* initialize context with a provided 64-byte vector basis (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512initBasis ( FNV512context * const ctx, | int FNV512initBasis ( FNV512context * const ctx, | |||
| const uint8_t basis[FNV512size] ) { | const uint8_t basis[FNV512size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV512size/2; ++i ) { | for ( int i=0; i < FNV512size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV512state; | ctx->Computed = FNVinited+FNV512state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV512initBasis */ | } /* end FNV512initBasis */ | |||
| /* hash in a counted block (32-bit) | /* hash in a counted block (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV512blockin ( FNV512context * const ctx, | int FNV512blockin ( FNV512context * const ctx, | |||
| const void *vin, | const void *vin, | |||
| long int length ) { | long int length ) { | |||
| skipping to change at line 4125 ¶ | skipping to change at line 4126 ¶ | |||
| } FNV1024context; | } FNV1024context; | |||
| #endif /* FNV_64bitIntegers */ | #endif /* FNV_64bitIntegers */ | |||
| /* Function Prototypes: | /* Function Prototypes: | |||
| * | * | |||
| * FNV1024string: hash a zero-terminated string not including | * FNV1024string: hash a zero-terminated string not including | |||
| * the terminating zero | * the terminating zero | |||
| * FNV1024stringBasis: also takes an offset_basis parameter | * FNV1024stringBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV1024block: hash a specified length byte vector | * FNV1024block: hash a byte vector of a specified length | |||
| * FNV1024blockBasis: also takes an offset_basis parameter | * FNV1024blockBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV1024file: hash the contents of a file | * FNV1024file: hash the contents of a file | |||
| * FNV1024fileBasis: also takes an offset_basis parameter | * FNV1024fileBasis: also takes an offset_basis parameter | |||
| * | * | |||
| * FNV1024init: initializes an FNV1024 context | * FNV1024init: initializes an FNV1024 context | |||
| * FNV1024initBasis: initializes an FNV1024 context with a | * FNV1024initBasis: initializes an FNV1024 context with a | |||
| * provided 128-byte vector basis | * provided 128-byte vector basis | |||
| * FNV1024blockin: hash in a specified length byte vector | * FNV1024blockin: hash in a byte vector of a specified length | |||
| * FNV1024stringin: hash in a zero-terminated string not | * FNV1024stringin: hash in a zero-terminated string not | |||
| * including the terminating zero | * including the terminating zero | |||
| * FNV1024filein: hash in the contents of a file | * FNV1024filein: hash in the contents of a file | |||
| * FNV1024result: returns the hash value | * FNV1024result: returns the hash value | |||
| * | * | |||
| * Hash is returned as an array of 8-bit unsigned integers | * Hash is returned as an array of 8-bit unsigned integers | |||
| */ | */ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| extern "C" { | extern "C" { | |||
| skipping to change at line 4206 ¶ | skipping to change at line 4207 ¶ | |||
| #include <stdio.h> | #include <stdio.h> | |||
| #include "fnv-private.h" | #include "fnv-private.h" | |||
| #include "FNV1024.h" | #include "FNV1024.h" | |||
| //***************************************************************** | //***************************************************************** | |||
| // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | // COMMON CODE FOR 64- AND 32-BIT INTEGER MODES | |||
| //***************************************************************** | //***************************************************************** | |||
| /* FNV1024 hash a zero-terminated string not including the zero | /* FNV1024: hash a zero-terminated string not including the zero | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024string ( const char *in, uint8_t out[FNV1024size] ) { | int FNV1024string ( const char *in, uint8_t out[FNV1024size] ) { | |||
| FNV1024context ctx; | FNV1024context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV1024init ( &ctx )) ) | if ( (error = FNV1024init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV1024stringin ( &ctx, in )) ) | if ( (error = FNV1024stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV1024result ( &ctx, out ); | return FNV1024result ( &ctx, out ); | |||
| } /* end FNV1024string */ | } /* end FNV1024string */ | |||
| /* FNV1024 hash a zero-terminated string not including the zero | /* FNV1024: hash a zero-terminated string not including the zero | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024stringBasis ( const char *in, | int FNV1024stringBasis ( const char *in, | |||
| uint8_t out[FNV1024size], | uint8_t out[FNV1024size], | |||
| const uint8_t basis[FNV1024size] ) { | const uint8_t basis[FNV1024size] ) { | |||
| FNV1024context ctx; | FNV1024context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV1024initBasis ( &ctx, basis )) ) | if ( (error = FNV1024initBasis ( &ctx, basis )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV1024stringin ( &ctx, in )) ) | if ( (error = FNV1024stringin ( &ctx, in )) ) | |||
| return error; | return error; | |||
| return FNV1024result ( &ctx, out ); | return FNV1024result ( &ctx, out ); | |||
| } /* end FNV1024stringBasis */ | } /* end FNV1024stringBasis */ | |||
| /* FNV1024 hash a counted block (64/32-bit) | /* FNV1024: hash a counted block (64/32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024block ( const void *vin, | int FNV1024block ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV1024size] ) { | uint8_t out[FNV1024size] ) { | |||
| FNV1024context ctx; | FNV1024context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV1024init ( &ctx )) ) | if ( (error = FNV1024init ( &ctx )) ) | |||
| return error; | return error; | |||
| if ( (error = FNV1024blockin ( &ctx, vin, length)) ) | if ( (error = FNV1024blockin ( &ctx, vin, length)) ) | |||
| return error; | return error; | |||
| return FNV1024result ( &ctx, out ); | return FNV1024result ( &ctx, out ); | |||
| } /* end FNV1024block */ | } /* end FNV1024block */ | |||
| /* FNV1024 hash a counted block (64/32-bit) | /* FNV1024: hash a counted block (64/32-bit) | |||
| * with a non-standard basis | * with a non-standard basis | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024blockBasis ( const void *vin, | int FNV1024blockBasis ( const void *vin, | |||
| long int length, | long int length, | |||
| uint8_t out[FNV1024size], | uint8_t out[FNV1024size], | |||
| const uint8_t basis[FNV1024size] ) { | const uint8_t basis[FNV1024size] ) { | |||
| FNV1024context ctx; | FNV1024context ctx; | |||
| int error; | int error; | |||
| if ( (error = FNV1024initBasis ( &ctx, basis )) ) | if ( (error = FNV1024initBasis ( &ctx, basis )) ) | |||
| skipping to change at line 4507 ¶ | skipping to change at line 4508 ¶ | |||
| } /* end FNV1024result */ | } /* end FNV1024result */ | |||
| //****************************************************************// | //****************************************************************// | |||
| // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | // END VERSION FOR WHEN YOU HAVE 64-BIT ARITHMETIC | |||
| //****************************************************************// | //****************************************************************// | |||
| #else /* FNV_64bitIntegers */ | #else /* FNV_64bitIntegers */ | |||
| //****************************************************************// | //****************************************************************// | |||
| // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | // START VERSION FOR WHEN YOU ONLY HAVE 32-BIT ARITHMETIC | |||
| //****************************************************************// | //****************************************************************// | |||
| /* version for when you only have 32-bit arithmetic | ||||
| ******************************************************************/ | ||||
| /* | /* | |||
| 1024-bit FNV_prime = 2^680 + 2^8 + 0x8d = | 1024-bit FNV_prime = 2^680 + 2^8 + 0x8d = | |||
| 0x00000000 00000000 00000000 00000000 | 0x00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000100 00000000 | 00000000 00000000 00000100 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 00000000 | 00000000 00000000 00000000 00000000 | |||
| 00000000 00000000 00000000 0000018D */ | 00000000 00000000 00000000 0000018D */ | |||
| skipping to change at line 4557 ¶ | skipping to change at line 4555 ¶ | |||
| } /* end FNV1024init */ | } /* end FNV1024init */ | |||
| /* initialize context with a provided 128-byte vector basis (32-bit) | /* initialize context with a provided 128-byte vector basis (32-bit) | |||
| *******************************************************************/ | *******************************************************************/ | |||
| int FNV1024initBasis ( FNV1024context * const ctx, | int FNV1024initBasis ( FNV1024context * const ctx, | |||
| const uint8_t basis[FNV1024size] ) { | const uint8_t basis[FNV1024size] ) { | |||
| if ( !ctx || !basis ) | if ( !ctx || !basis ) | |||
| return fnvNull; | return fnvNull; | |||
| for ( int i=0; i < FNV1024size/2; ++i ) { | for ( int i=0; i < FNV1024size/2; ++i ) { | |||
| uint32_t temp = *basis++; | uint32_t temp = *basis++; | |||
| ctx->Hash[i] = ( temp<<8 ) + *basis++; | ctx->Hash[i] = ( temp<<8 ) + *basis++; | |||
| } | } | |||
| ctx->Computed = FNVinited+FNV1024state; | ctx->Computed = FNVinited+FNV1024state; | |||
| return fnvSuccess; | return fnvSuccess; | |||
| } /* end FNV1024initBasis */ | } /* end FNV1024initBasis */ | |||
| /* hash in a counted block (32-bit) | /* hash in a counted block (32-bit) | |||
| ******************************************************************/ | ******************************************************************/ | |||
| int FNV1024blockin ( FNV1024context * const ctx, | int FNV1024blockin ( FNV1024context * const ctx, | |||
| const void *vin, | const void *vin, | |||
| long int length ) { | long int length ) { | |||
| skipping to change at line 4707 ¶ | skipping to change at line 4705 ¶ | |||
| #include "FNV64.h" | #include "FNV64.h" | |||
| #include "FNV128.h" | #include "FNV128.h" | |||
| #include "FNV256.h" | #include "FNV256.h" | |||
| #include "FNV512.h" | #include "FNV512.h" | |||
| #include "FNV1024.h" | #include "FNV1024.h" | |||
| /* global variables */ | /* global variables */ | |||
| char *funcName = "funcName not set?"; | char *funcName = "funcName not set?"; | |||
| const char *errteststring = "foo"; | const char *errteststring = "foo"; | |||
| int Terr = -1; /* Total errors */ | int Terr = -1; /* Total errors */ | |||
| int verbose = 0; /* verbose flag */ | int verbose = 0; /* Verbose flag */ | |||
| enum { FNV32selected = 0, FNV64selected, FNV128selected, | enum { FNV32selected = 0, FNV64selected, FNV128selected, | |||
| FNV256selected, FNV512selected, FNV1024selected, | FNV256selected, FNV512selected, FNV1024selected, | |||
| FNVnone = -1 } selected = FNVnone; | FNVnone = -1 } selected = FNVnone; | |||
| #define NTestBytes 3 | #define NTestBytes 3 | |||
| const uint8_t errtestbytes[NTestBytes] = { (uint8_t)1, | const uint8_t errtestbytes[NTestBytes] = { (uint8_t)1, | |||
| (uint8_t)2, (uint8_t)3 }; | (uint8_t)2, (uint8_t)3 }; | |||
| // initial teststring is null, so initial result is offset_basis | // initial teststring is null, so initial result is offset_basis | |||
| const char *teststring[] = { | const char *teststring[] = { | |||
| "", | "", | |||
| "a", | "a", | |||
| "foobar", | "foobar", | |||
| "Hello!\x01\xFF\xED" | "Hello!\x01\xFF\xED" | |||
| }; | }; | |||
| #define NTstrings (sizeof(teststring)/sizeof(char *)) | #define NTstrings (sizeof(teststring)/sizeof(char *)) | |||
| // due to FNV-1 versus FNV1a, xor in final backslash separately | // due to FNV-1 versus FNV1a, XOR in final backslash separately | |||
| const char BasisString[] = "chongo <Landon Curt Noll> /\\../"; | const char BasisString[] = "chongo <Landon Curt Noll> /\\../"; | |||
| FNV32context e32Context; | FNV32context e32Context; | |||
| uint32_t eUint32 = 42; | uint32_t eUint32 = 42; | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| uint64_t eUint64 = 42; | uint64_t eUint64 = 42; | |||
| #endif | #endif | |||
| FNV64context e64Context; | FNV64context e64Context; | |||
| FNV128context e128Context; | FNV128context e128Context; | |||
| FNV256context e256Context; | FNV256context e256Context; | |||
| FNV512context e512Context; | FNV512context e512Context; | |||
| skipping to change at line 4814 ¶ | skipping to change at line 4812 ¶ | |||
| //**************************************************************** | //**************************************************************** | |||
| int main( int argc, const char **argv ) { | int main( int argc, const char **argv ) { | |||
| int option; // command line option letter | int option; // command line option letter | |||
| int i; | int i; | |||
| uint16_t endianness = 5*256 + 11; | uint16_t endianness = 5*256 + 11; | |||
| mkstemp(tempFileNameTemplate); | mkstemp(tempFileNameTemplate); | |||
| tempFileName = tempFileNameTemplate; | tempFileName = tempFileNameTemplate; | |||
| if ( ((uint8_t *)&endianness)[0] != 11 ) | if ( ((uint8_t *)&endianness)[0] != 11 ) | |||
| printf ("Coded for Little Endian but computer seems\n" | printf ("Coded for little endian but computer seems\n" | |||
| " to be Big Endian! Multi-byte integer results\n" | " to be big endian! Multi-byte integer results\n" | |||
| " may be incorrect!\n"); | " may be incorrect!\n"); | |||
| for ( i=0; i<FNV1024size; ++i ) {// initialize a couple of arrays | for ( i=0; i<FNV1024size; ++i ) {// initialize a couple of arrays | |||
| ZeroBasis[i] = 0; | ZeroBasis[i] = 0; | |||
| FakeBasis[i] = (uint8_t)i; | FakeBasis[i] = (uint8_t)i; | |||
| } | } | |||
| if ( argc == 1 ) { // if no arguments | if ( argc == 1 ) { // if no arguments | |||
| TestAll(); | TestAll(); | |||
| if ( tempFileName ) | if ( tempFileName ) | |||
| unlink(tempFileName); | unlink(tempFileName); | |||
| exit(0); | exit(0); | |||
| skipping to change at line 4855 ¶ | skipping to change at line 4853 ¶ | |||
| if ( funcmap[selected].Filefunc ( optarg, hash )) | if ( funcmap[selected].Filefunc ( optarg, hash )) | |||
| printf ( "Hashing file '%s' fails: %s.\n", | printf ( "Hashing file '%s' fails: %s.\n", | |||
| optarg, strerror(errno) ); | optarg, strerror(errno) ); | |||
| else | else | |||
| HexPrint ( funcmap[selected].length/8, hash ); | HexPrint ( funcmap[selected].length/8, hash ); | |||
| printf ( "\n" ); | printf ( "\n" ); | |||
| break; | break; | |||
| case 'h': // help | case 'h': // help | |||
| usage( argv[0] ); | usage( argv[0] ); | |||
| break; | break; | |||
| case 't': // follow by size of FNV to test, 0->all | case 't': // followed by size of FNV to test, 0->all | |||
| selected = find_selected(optarg); | selected = find_selected(optarg); | |||
| if (selected == FNVnone) | if (selected == FNVnone) | |||
| printf ( "Bad argument to option -t\n" | printf ( "Bad argument to option -t\n" | |||
| "Valid sizes are 32, 64, 128," | "Valid sizes are 32, 64, 128," | |||
| " 256, 512, and 1024\n"); | " 256, 512, and 1024\n" ); | |||
| else | else | |||
| funcmap[selected].Testfunc(); // invoke test | funcmap[selected].Testfunc(); // invoke test | |||
| break; | break; | |||
| case 'u': // follow by size of FNV to use | case 'u': // followed by size of FNV to use | |||
| selected = find_selected(optarg); | selected = find_selected(optarg); | |||
| if ( selected == FNVnone ) | if ( selected == FNVnone ) | |||
| printf ( "Bad argument to option -u\n" | printf ( "Bad argument to option -u\n" | |||
| "Valid sizes are 32, 64, 128," | "Valid sizes are 32, 64, 128," | |||
| "256, 512, and 1024\n" ); | " 256, 512, and 1024\n" ); | |||
| break; | break; | |||
| case 'v': // toggle Verbose flag | case 'v': // toggle Verbose flag | |||
| if ( (verbose ^= 1) ) { | if ( (verbose ^= 1) ) { | |||
| printf ( "Verbose on.\n" ); | printf ( "Verbose on.\n" ); | |||
| #ifdef FNV_64bitIntegers | #ifdef FNV_64bitIntegers | |||
| printf ("Has 64-bit Integers. "); | printf ("Has 64-bit integers. "); | |||
| #else | #else | |||
| printf ("Does not have 64-bit integers. "); | printf ("Does not have 64-bit integers. "); | |||
| #endif | #endif | |||
| // also tests the TestR function | // also tests the TestR function | |||
| funcName = "Testing TestR"; | funcName = "Testing TestR"; | |||
| TestR ( "should fail", 1, 2 ); | TestR ( "should fail", 1, 2 ); | |||
| TestR ( "should not have failed", 3, 3 ); | TestR ( "should not have failed", 3, 3 ); | |||
| } | } | |||
| else | else | |||
| printf ( "Verbose off.\n" ); | printf ( "Verbose off.\n" ); | |||
| skipping to change at line 4928 ¶ | skipping to change at line 4926 ¶ | |||
| if ( tempFileName ) | if ( tempFileName ) | |||
| unlink(tempFileName); | unlink(tempFileName); | |||
| return 0; | return 0; | |||
| } /* end main */ | } /* end main */ | |||
| /* Write to a temp file | /* Write to a temp file | |||
| ******************************************************************/ | ******************************************************************/ | |||
| const char *WriteTemp( const char *str, long int iLen ) { | const char *WriteTemp( const char *str, long int iLen ) { | |||
| FILE *fp = fopen( tempFileName, "w" ); | FILE *fp = fopen( tempFileName, "w" ); | |||
| if (!fp) { | if (!fp) { | |||
| printf( "Cannot open tempfile: %s: %s\n", | printf ( "Cannot open tempfile: %s: %s\n", | |||
| tempFileName, strerror(errno) ); | tempFileName, strerror(errno) ); | |||
| return 0; | return 0; | |||
| } | } | |||
| long int ret = fwrite( str, 1, iLen, fp ); | long int ret = fwrite( str, 1, iLen, fp ); | |||
| fclose(fp); | fclose(fp); | |||
| if ( ret != iLen ) { | if ( ret != iLen ) { | |||
| printf( "Cannot write tempfile: %s: %s\n", | printf ( "Cannot write tempfile: %s: %s\n", | |||
| tempFileName, strerror(errno) ); | tempFileName, strerror(errno) ); | |||
| return 0; | return 0; | |||
| } | } | |||
| return tempFileName; | return tempFileName; | |||
| } | } | |||
| //**************************************************************** | //**************************************************************** | |||
| // Test status return code | // Test status return code | |||
| //**************************************************************** | //**************************************************************** | |||
| int TestR ( const char *name, int expect, int actual ) { | int TestR ( const char *name, int expect, int actual ) { | |||
| if ( expect != actual ) { | if ( expect != actual ) { | |||
| skipping to change at line 5073 ¶ | skipping to change at line 5071 ¶ | |||
| TestR ( "blk2b", fnvBadParam, | TestR ( "blk2b", fnvBadParam, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, -1, | funcmap[selected].BlockBasisfunc ( errtestbytes, -1, | |||
| hash, FakeBasis ) ); | hash, FakeBasis ) ); | |||
| TestR ( "blk3b", fnvNull, | TestR ( "blk3b", fnvNull, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | |||
| (uint8_t *)0, FakeBasis ) ); | (uint8_t *)0, FakeBasis ) ); | |||
| TestR ( "blk4b", fnvNull, | TestR ( "blk4b", fnvNull, | |||
| funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | funcmap[selected].BlockBasisfunc ( errtestbytes, 1, | |||
| hash, (uint8_t *)0 ) ); | hash, (uint8_t *)0 ) ); | |||
| TestR ( "file1", fnvNull, | TestR ( "file1", fnvNull, | |||
| funcmap[selected].Filefunc ( (char *)0, hash )); | funcmap[selected].Filefunc ( (char *)0, hash ) ); | |||
| TestR ( "file2", fnvNull, | TestR ( "file2", fnvNull, | |||
| funcmap[selected].Filefunc ( "foo.txt", (uint8_t *)0 )); | funcmap[selected].Filefunc ( "foo.txt", (uint8_t *)0 ) ); | |||
| TestR ( "file1b", fnvNull, | TestR ( "file1b", fnvNull, | |||
| funcmap[selected].FileBasisfunc ( (char *)0, hash, | funcmap[selected].FileBasisfunc ( (char *)0, hash, | |||
| FakeBasis )); | FakeBasis ) ); | |||
| TestR ( "file2b", fnvNull, | TestR ( "file2b", fnvNull, | |||
| funcmap[selected].FileBasisfunc ( "foo.txt", (uint8_t *)0, | funcmap[selected].FileBasisfunc ( "foo.txt", (uint8_t *)0, | |||
| FakeBasis )); | FakeBasis ) ); | |||
| TestR ( "file3b", fnvNull, | TestR ( "file3b", fnvNull, | |||
| funcmap[selected].FileBasisfunc ( "foo.txt", hash, | funcmap[selected].FileBasisfunc ( "foo.txt", hash, | |||
| (uint8_t *)0 )); | (uint8_t *)0 ) ); | |||
| } /* end CommonTest */ | } /* end CommonTest */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // Print command line help | // Print command line help | |||
| //**************************************************************** | //**************************************************************** | |||
| void usage( const char *argv0 ) { | void usage( const char *argv0 ) { | |||
| printf ( | printf ( | |||
| "%s [-a] [-t nnn] [-u nnn] [-v] [-f filename] [token ...]\n" | "%s [-a] [-t nnn] [-u nnn] [-v] [-f filename] [token ...]\n" | |||
| " -a = run all tests\n" | " -a = run all tests\n" | |||
| " -f filename = hash file contents\n" | " -f filename = hash file contents\n" | |||
| skipping to change at line 5108 ¶ | skipping to change at line 5106 ¶ | |||
| " -v = toggle Verbose flag\n" | " -v = toggle Verbose flag\n" | |||
| " Each token is hashed.\n", argv0 ); | " Each token is hashed.\n", argv0 ); | |||
| } /* end usage */ | } /* end usage */ | |||
| //**************************************************************** | //**************************************************************** | |||
| // Test Macros | // Test Macros | |||
| //**************************************************************** | //**************************************************************** | |||
| // test for return values | // test for return values | |||
| //************************ | //************************ | |||
| #define TestInit(INIT,CTX,CTXT) \ | #define TestInit(INIT,CTX,CTXT) \ | |||
| TestR ( "init1", fnvSuccess, INIT ( &CTX ) ); \ | TestR ( "init1", fnvSuccess, INIT ( &CTX ) ); \ | |||
| TestR ( "init2", fnvNull, INIT ( (CTXT *)0 ) ); | TestR ( "init2", fnvNull, INIT ( (CTXT *)0 ) ); | |||
| #define TestInitBasis(INITB,CTX,CTXT) \ | #define TestInitBasis(INITB,CTX,CTXT) \ | |||
| TestR ( "initB1", fnvSuccess, INITB (&CTX, FakeBasis )); \ | TestR ( "initB1", fnvSuccess, INITB (&CTX, FakeBasis ) ); | |||
| TestR ( "initB2", fnvNull, INITB ( (CTXT *)0, hash ) ); \ | TestR ( "initB2", fnvNull, INITB ( (CTXT *)0, hash ) ); \ | |||
| TestR ( "initB3", fnvNull, INITB ( &CTX, (uint8_t *)0 )); | TestR ( "initB3", fnvNull, INITB ( &CTX, (uint8_t *)0 ) ); | |||
| #define TestBlockin(BLKIN,CTX,CTXT) \ | #define TestBlockin(BLKIN,CTX,CTXT) \ | |||
| TestR ( "blockin1", fnvNull, \ | TestR ( "blockin1", fnvNull, \ | |||
| BLKIN ( (CTXT *)0, errtestbytes, NTestBytes ) ); \ | BLKIN ( (CTXT *)0, errtestbytes, NTestBytes ) ); \ | |||
| TestR ( "blockin2", fnvNull, \ | TestR ( "blockin2", fnvNull, \ | |||
| BLKIN ( &CTX, (uint8_t *)0, NTestBytes ) ); \ | BLKIN ( &CTX, (uint8_t *)0, NTestBytes ) ); \ | |||
| TestR ( "blockin3", fnvBadParam, \ | TestR ( "blockin3", fnvBadParam, \ | |||
| BLKIN ( &CTX, errtestbytes, -1 ) ); \ | BLKIN ( &CTX, errtestbytes, -1 ) ); \ | |||
| TestR ( "blockin4", fnvStateError, \ | TestR ( "blockin4", fnvStateError, \ | |||
| BLKIN ( &CTX, errtestbytes, NTestBytes ) ); | BLKIN ( &CTX, errtestbytes, NTestBytes ) ); | |||
| #define TestStringin(STRIN,CTX,CTXT) \ | #define TestStringin(STRIN,CTX,CTXT) \ | |||
| TestR ( "stringin1", fnvNull, \ | TestR ( "stringin1", fnvNull, \ | |||
| STRIN ( (CTXT *)0, errteststring ) ); \ | STRIN ( (CTXT *)0, errteststring ) ); \ | |||
| TestR ( "stringin2", fnvNull, STRIN ( &CTX, (char *)0 ) ); \ | TestR ( "stringin2", fnvNull, STRIN ( &CTX, (char *)0 ) ); \ | |||
| TestR ( "stringin3", fnvStateError, \ | TestR ( "stringin3", fnvStateError, \ | |||
| STRIN ( &CTX, errteststring ) ); | STRIN ( &CTX, errteststring ) ); | |||
| #define TestFilein(FLIN,CTX,CTXT) \ | #define TestFilein(FLIN,CTX,CTXT) \ | |||
| TestR ( "file1", fnvNull, FLIN ( (CTXT *)0, errteststring ) );\ | TestR ( "file1", fnvNull, FLIN ( (CTXT *)0, errteststring ) ); \ | |||
| TestR ( "file2", fnvNull, FLIN ( &CTX, (char *)0 ) ); \ | TestR ( "file2", fnvNull, FLIN ( &CTX, (char *)0 ) ); \ | |||
| TestR ( "file3", fnvStateError, \ | TestR ( "file3", fnvStateError, \ | |||
| FLIN ( &CTX, errteststring ) ); | FLIN ( &CTX, errteststring ) ); | |||
| #define TestResult(RSLT,CTX,CTXT) \ | #define TestResult(RSLT,CTX,CTXT) \ | |||
| TestR ( "result1", fnvNull, RSLT ( (CTXT *)0, hash ) ); \ | TestR ( "result1", fnvNull, RSLT ( (CTXT *)0, hash ) ); \ | |||
| TestR ( "result2", fnvNull, RSLT ( &CTX, (uint8_t *)0 ) ); \ | TestR ( "result2", fnvNull, RSLT ( &CTX, (uint8_t *)0 ) ); \ | |||
| TestR ( "result3", fnvStateError, \ | TestR ( "result3", fnvStateError, \ | |||
| FNV128result ( &e128Context, hash ) ); | FNV128result ( &e128Context, hash ) ); | |||
| // test return values for INT versions including non-std basis | // test return values for INT versions including non-std basis | |||
| //************************************************************* | //************************************************************* | |||
| #define TestINT(STRINT,STRINTB,BLKINT,BLKINTB,INITINTB, \ | #define TestINT(STRINT,STRINTB,BLKINT,BLKINTB,INITINTB, \ | |||
| INTV,INTVT,ctxT) \ | INTV,INTVT,ctxT) \ | |||
| TestR ( "string1i", fnvNull, STRINT ( (char *)0, &INTV ) ); \ | TestR ( "string1i", fnvNull, STRINT ( (char *)0, &INTV ) ); \ | |||
| TestR ( "string2i", fnvNull, \ | TestR ( "string2i", fnvNull, \ | |||
| STRINT ( errteststring, (INTVT *)0 ) ); \ | STRINT ( errteststring, (INTVT *)0 ) ); \ | |||
| TestR ("string3i", fnvNull, STRINTB ((char *)0, &INTV, INTV));\ | TestR ( "string3i", fnvNull, STRINTB ((char *)0, &INTV, INTV) );\ | |||
| TestR ( "string4i", fnvNull, \ | TestR ( "string4i", fnvNull, \ | |||
| STRINTB (errteststring, (INTVT *)0, INTV)); \ | STRINTB (errteststring, (INTVT *)0, INTV) ); \ | |||
| TestR ("block1i", fnvNull, BLKINT ( (uint8_t *)0, 1, &INTV ));\ | TestR ( "block1i", fnvNull, BLKINT ( (uint8_t *)0, 1, &INTV ) );\ | |||
| TestR ( "block2i", fnvBadParam, \ | TestR ( "block2i", fnvBadParam, \ | |||
| BLKINT ( errtestbytes, -1, &INTV ) ); \ | BLKINT ( errtestbytes, -1, &INTV ) ); \ | |||
| TestR ( "block3i", fnvNull, \ | TestR ( "block3i", fnvNull, \ | |||
| BLKINT ( errtestbytes, 1, (INTVT *)0 ) ); \ | BLKINT ( errtestbytes, 1, (INTVT *)0 ) ); \ | |||
| TestR ( "block4i", fnvNull, \ | TestR ( "block4i", fnvNull, \ | |||
| BLKINTB ( (uint8_t *)0, 1, &INTV, INTV ) ); \ | BLKINTB ( (uint8_t *)0, 1, &INTV, INTV ) ); \ | |||
| TestR ( "block5i", fnvBadParam, \ | TestR ( "block5i", fnvBadParam, \ | |||
| BLKINTB ( errtestbytes, -1, &INTV, INTV ) ); \ | BLKINTB ( errtestbytes, -1, &INTV, INTV ) ); \ | |||
| TestR ( "block6i", fnvNull, \ | TestR ( "block6i", fnvNull, \ | |||
| BLKINTB ( errtestbytes, 1, (INTVT *)0, INTV ) ); \ | BLKINTB ( errtestbytes, 1, (INTVT *)0, INTV ) ); \ | |||
| TestR ("initBasis1i", fnvNull, INITINTB ( (ctxT *)0, INTV )); | TestR ( "initBasis1i", fnvNull, INITINTB ( (ctxT *)0, INTV ) ); | |||
| #define TestINTrf(RSLTINT,FILEINT,FILEINTB, \ | #define TestINTrf(RSLTINT,FILEINT,FILEINTB, \ | |||
| ctx,ctxT,INTV,INTVT) \ | ctx,ctxT,INTV,INTVT) \ | |||
| TestR ( "result1i", fnvNull, RSLTINT ( (ctxT *)0, &INTV ) ); \ | TestR ( "result1i", fnvNull, RSLTINT ( (ctxT *)0, &INTV ) ); \ | |||
| TestR ( "result2i", fnvNull, RSLTINT ( &ctx, (INTVT *)0 ) ); \ | TestR ( "result2i", fnvNull, RSLTINT ( &ctx, (INTVT *)0 ) ); \ | |||
| TestR ( "result3i", fnvStateError, RSLTINT ( &ctx, &INTV ) ); \ | TestR ( "result3i", fnvStateError, RSLTINT ( &ctx, &INTV ) ); \ | |||
| TestR ( "file1i", fnvNull, FILEINT ( (char *)0, &INTV )); \ | TestR ( "file1i", fnvNull, FILEINT ( (char *)0, &INTV ) ); \ | |||
| TestR ( "file2i", fnvNull, FILEINT ( "foo.txt", (INTVT *)0 ));\ | TestR ( "file2i", fnvNull, FILEINT ( "foo.txt", (INTVT *)0 ) ); \ | |||
| TestR ("file3i", fnvNull, FILEINTB ( (char *)0, &INTV, INTV));\ | TestR ( "file3i", fnvNull, FILEINTB ( (char *)0, &INTV, INTV) );\ | |||
| TestR ( "file4i", fnvNull, \ | TestR ( "file4i", fnvNull, \ | |||
| FILEINTB ( "foo.txt", (INTVT *)0, INTV )); | FILEINTB ( "foo.txt", (INTVT *)0, INTV ) ); | |||
| // test to calculate standard basis from basis zero FNV-1 | // test to calculate standard basis from basis zero FNV-1 | |||
| // depends on zero basis making the initial multiply a no-op | // depends on zero basis making the initial multiply a no-op | |||
| //***************************** | //***************************** | |||
| #define BasisZero(STRING,SIZ,VALUE) \ | #define BasisZero(STRING,SIZ,VALUE) \ | |||
| err = TestR ( "fnv0s", fnvSuccess, \ | err = TestR ( "fnv0s", fnvSuccess, \ | |||
| STRING ( BasisString, hash, ZeroBasis ) ); \ | STRING ( BasisString, hash, ZeroBasis ) ); \ | |||
| if ( err == fnvSuccess ) { \ | if ( err == fnvSuccess ) { \ | |||
| hash[SIZ-1] ^= '\\'; \ | hash[SIZ-1] ^= '\\'; \ | |||
| TestNValue ("fnv0sv", BasisString, SIZ, hash, VALUE[0]); \ | TestNValue ( "fnv0sv", BasisString, SIZ, hash, VALUE[0] ); \ | |||
| } | } | |||
| #define BasisINTZero(STRINT,SIZ,VALUE,INTV,INTVT) \ | #define BasisINTZero(STRINT,SIZ,VALUE,INTV,INTVT) \ | |||
| err = TestR ( "fnv0s", fnvSuccess, \ | err = TestR ( "fnv0s", fnvSuccess, \ | |||
| STRINT ( BasisString, &INTV, (INTVT) 0 ) ); \ | STRINT ( BasisString, &INTV, (INTVT) 0 ) ); \ | |||
| if ( err == fnvSuccess ) { \ | if ( err == fnvSuccess ) { \ | |||
| INTV ^= '\\'; \ | INTV ^= '\\'; \ | |||
| TestNValue ("fnv0svi", BasisString, SIZ, \ | TestNValue ( "fnv0svi", BasisString, SIZ, \ | |||
| (uint8_t *)&INTV, (uint8_t *)&VALUE[0]); \ | (uint8_t *)&INTV, (uint8_t *)&VALUE[0] ); \ | |||
| } | } | |||
| // test for return hash values | // test for return hash values | |||
| //***************************** | //***************************** | |||
| #define TestSTRBLKHash(STR,BLK,SVAL,BVAL,SZ) \ | #define TestSTRBLKHash(STR,BLK,SVAL,BVAL,SZ) \ | |||
| if ( TestR ( "stringa", fnvSuccess, \ | if ( TestR ( "stringa", fnvSuccess, \ | |||
| STR ( teststring[i], hash ) ) ) \ | STR ( teststring[i], hash ) ) ) \ | |||
| printf ( " Index = %i\n", i ); \ | printf ( " Index = %i\n", i ); \ | |||
| else \ | else \ | |||
| TestNValue ( "stringb", teststring[i], SZ, \ | TestNValue ( "stringb", teststring[i], SZ, \ | |||
| hash, (uint8_t *)&SVAL[i] ); \ | hash, (uint8_t *)&SVAL[i] ); \ | |||
| if ( TestR ( "blocka", fnvSuccess, BLK ( teststring[i], \ | if ( TestR ( "blocka", fnvSuccess, BLK ( teststring[i], \ | |||
| (long int)(strlen(teststring[i])+1), hash ) ) ) \ | (long int)(strlen(teststring[i])+1), hash ) ) ) \ | |||
| printf ( " Index = %i\n", i ); \ | printf ( " Index = %i\n", i ); \ | |||
| else \ | else \ | |||
| TestNValue ( "blockb", teststring[i], SZ, \ | TestNValue ( "blockb", teststring[i], SZ, \ | |||
| hash, (uint8_t *)&BVAL[i] ); | hash, (uint8_t *)&BVAL[i] ); | |||
| // Test incremental functions | // Test incremental functions | |||
| //**************************** | //**************************** | |||
| #define IncrHash(INIT,CTX,BLK,RSLT,INITB,STR,SZ,SVAL) \ | #define IncrHash(INIT,CTX,BLK,RSLT,INITB,STR,SZ,SVAL) \ | |||
| err = TestR ( "inita", fnvSuccess, INIT ( &CTX ) ); \ | err = TestR ( "inita", fnvSuccess, INIT ( &CTX ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| iLen = strlen ( teststring[i] ); \ | iLen = strlen ( teststring[i] ); \ | |||
| err = TestR ("blockina", fnvSuccess, \ | err = TestR ( "blockina", fnvSuccess, \ | |||
| BLK ( &CTX, (uint8_t *)teststring[i], iLen/2 )); \ | BLK ( &CTX, (uint8_t *)teststring[i], iLen/2 ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| if ( i & 1 ) { \ | if ( i & 1 ) { \ | |||
| err = TestR ("basisra", fnvSuccess, RSLT ( &CTX, hash )); \ | err = TestR ( "basisra", fnvSuccess, RSLT ( &CTX, hash ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| err = TestR ("basisia", fnvSuccess, INITB ( &CTX, hash ));\ | err = TestR ( "basisia", fnvSuccess, INITB ( &CTX, hash ) );\ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| } \ | } \ | |||
| err = TestR ( "stringina", fnvSuccess, STR ( &CTX, \ | err = TestR ( "stringina", fnvSuccess, STR ( &CTX, \ | |||
| teststring[i] + iLen/2 ) ); \ | teststring[i] + iLen/2 ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| err = TestR ( "resulta", fnvSuccess, RSLT ( &CTX, hash ) ); \ | err = TestR ( "resulta", fnvSuccess, RSLT ( &CTX, hash ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| TestNValue ( "incrementala", teststring[i], SZ, \ | TestNValue ( "incrementala", teststring[i], SZ, \ | |||
| hash, (uint8_t *)&SVAL[i] ); | hash, (uint8_t *)&SVAL[i] ); | |||
| // test file hash | // test file hash | |||
| //***************************** | //***************************** | |||
| #define TestFILEHash(FILE,BVAL,SZ) \ | #define TestFILEHash(FILE,BVAL,SZ) \ | |||
| err = TestR ( "fileafh", fnvSuccess, \ | err = TestR ( "fileafh", fnvSuccess, \ | |||
| FILE ( WriteTemp(teststring[i], iLen), \ | FILE ( WriteTemp(teststring[i], iLen), \ | |||
| hash ) ); \ | hash ) ); \ | |||
| if ( err ) break; \ | if ( err ) break; \ | |||
| TestNValue ( "filebfh", teststring[i], SZ, hash, \ | TestNValue ( "filebfh", teststring[i], SZ, hash, \ | |||
| (uint8_t *)&BVAL[i] ); | (uint8_t *)&BVAL[i] ); | |||
| //**************************************************************** | //**************************************************************** | |||
| // FNV32 Test | // FNV32 Test | |||
| //**************************************************************** | //**************************************************************** | |||
| void Test32 ( void ) { | void Test32 ( void ) { | |||
| long int iLen; | long int iLen; | |||
| uint32_t FNV32svalues[NTstrings] = { | uint32_t FNV32svalues[NTstrings] = { | |||
| 0x811c9dc5, 0xe40c292c, 0xbf9cf968, 0xfd9d3881 }; | 0x811c9dc5, 0xe40c292c, 0xbf9cf968, 0xfd9d3881 }; | |||
| uint32_t FNV32bvalues[NTstrings] = { | uint32_t FNV32bvalues[NTstrings] = { | |||
| skipping to change at line 5280 ¶ | skipping to change at line 5278 ¶ | |||
| e32Context.Computed = FNVclobber+FNV32state; | e32Context.Computed = FNVclobber+FNV32state; | |||
| TestBlockin (FNV32blockin, e32Context, FNV32context) | TestBlockin (FNV32blockin, e32Context, FNV32context) | |||
| TestStringin (FNV32stringin, e32Context, FNV32context) | TestStringin (FNV32stringin, e32Context, FNV32context) | |||
| TestFilein (FNV32filein, e32Context, FNV32context) | TestFilein (FNV32filein, e32Context, FNV32context) | |||
| TestResult (FNV32result, e32Context, FNV32context) | TestResult (FNV32result, e32Context, FNV32context) | |||
| TestINTrf(FNV32INTresult,FNV32INTfile,FNV32INTfileBasis, | TestINTrf(FNV32INTresult,FNV32INTfile,FNV32INTfileBasis, | |||
| e32Context,FNV32context,eUint32,uint32_t) | e32Context,FNV32context,eUint32,uint32_t) | |||
| ErrTestReport (); | ErrTestReport (); | |||
| Terr = 0; | Terr = 0; | |||
| err = TestR ( "fnv0s", fnvSuccess, | err = TestR ( "fnv0s", fnvSuccess, | |||
| FNV32stringBasis ( BasisString, hash, ZeroBasis )); | FNV32stringBasis ( BasisString, hash, ZeroBasis ) ); | |||
| if ( err == fnvSuccess ) { | if ( err == fnvSuccess ) { | |||
| hash[0] ^= '\\'; | hash[0] ^= '\\'; | |||
| TestNValue ( "fnv0sv32", BasisString, FNV32size, | TestNValue ( "fnv0sv32", BasisString, FNV32size, | |||
| hash, (uint8_t *)&FNV32svalues[0]); | hash, (uint8_t *)&FNV32svalues[0]); | |||
| } | } | |||
| BasisINTZero (FNV32INTstringBasis,FNV32size,FNV32svalues, \ | BasisINTZero (FNV32INTstringBasis,FNV32size,FNV32svalues, \ | |||
| eUint32,uint32_t) | eUint32,uint32_t) | |||
| for ( i = 0; i < NTstrings; ++i ) { | for ( i = 0; i < NTstrings; ++i ) { | |||
| /* test actual results int */ | /* test actual results int */ | |||
| err = TestR ( "stringai", fnvSuccess, | err = TestR ( "stringai", fnvSuccess, | |||
| skipping to change at line 5352 ¶ | skipping to change at line 5350 ¶ | |||
| FNV32stringin ( &e32Context, | FNV32stringin ( &e32Context, | |||
| teststring[i] + iLen/2 ) ); | teststring[i] + iLen/2 ) ); | |||
| if ( err ) break; | if ( err ) break; | |||
| err = TestR ( "resultab", fnvSuccess, | err = TestR ( "resultab", fnvSuccess, | |||
| FNV32result ( &e32Context, hash ) ); | FNV32result ( &e32Context, hash ) ); | |||
| if ( err ) break; | if ( err ) break; | |||
| TestNValue ( "incrementala", teststring[i], FNV32size, | TestNValue ( "incrementala", teststring[i], FNV32size, | |||
| hash, (uint8_t *)&FNV32svalues[i] ); | hash, (uint8_t *)&FNV32svalues[i] ); | |||
| /* now try testing file hash int */ | /* now try testing file hash int */ | |||
| err = TestR ( "fileafi", fnvSuccess, | err = TestR ( "fileafi", fnvSuccess, | |||
| FNV32INTfile ( | FNV32INTfile ( WriteTemp(teststring[i], iLen), | |||
| WriteTemp(teststring[i], iLen), | &eUint32 ) ); | |||
| &eUint32 ) | ||||
| ); | ||||
| if ( err ) break; | if ( err ) break; | |||
| TestNValue ( "filebfi", teststring[i], FNV32size, | TestNValue ( "filebfi", teststring[i], FNV32size, | |||
| (uint8_t *)&eUint32, | (uint8_t *)&eUint32, | |||
| (uint8_t *)&FNV32svalues[i] ); | (uint8_t *)&FNV32svalues[i] ); | |||
| /* now try testing file hash byte */ | /* now try testing file hash byte */ | |||
| TestFILEHash ( FNV32file, FNV32svalues, FNV32size ) | TestFILEHash ( FNV32file, FNV32svalues, FNV32size ) | |||
| } // end for i | } // end for i | |||
| ValueTestReport (); | ValueTestReport (); | |||
| } /* end Test32 */ | } /* end Test32 */ | |||
| skipping to change at line 5403 ¶ | skipping to change at line 5399 ¶ | |||
| TestBlockin (FNV64blockin, e64Context, FNV64context) | TestBlockin (FNV64blockin, e64Context, FNV64context) | |||
| TestStringin (FNV64stringin, e64Context, FNV64context) | TestStringin (FNV64stringin, e64Context, FNV64context) | |||
| TestFilein (FNV64filein, e64Context, FNV64context) | TestFilein (FNV64filein, e64Context, FNV64context) | |||
| TestResult (FNV64result, e64Context, FNV64context) | TestResult (FNV64result, e64Context, FNV64context) | |||
| TestINTrf(FNV64INTresult,FNV64INTfile,FNV64INTfileBasis, | TestINTrf(FNV64INTresult,FNV64INTfile,FNV64INTfileBasis, | |||
| e64Context,FNV64context,eUint64,uint64_t) | e64Context,FNV64context,eUint64,uint64_t) | |||
| ErrTestReport (); | ErrTestReport (); | |||
| /* test actual results int */ | /* test actual results int */ | |||
| Terr = 0; | Terr = 0; | |||
| err = TestR ( "fnv0s", fnvSuccess, | err = TestR ( "fnv0s", fnvSuccess, | |||
| FNV64stringBasis ( BasisString, hash, ZeroBasis )); | FNV64stringBasis ( BasisString, hash, ZeroBasis ) ); | |||
| if ( err == fnvSuccess ) { | if ( err == fnvSuccess ) { | |||
| hash[0] ^= '\\'; | hash[0] ^= '\\'; | |||
| TestNValue ( "fnv0sv64", BasisString, FNV64size, | TestNValue ( "fnv0sv64", BasisString, FNV64size, | |||
| hash, (uint8_t *)&FNV64svalues[0]); | hash, (uint8_t *)&FNV64svalues[0]); | |||
| } | } | |||
| BasisINTZero (FNV64INTstringBasis,FNV64size,FNV64svalues, \ | BasisINTZero (FNV64INTstringBasis,FNV64size,FNV64svalues, \ | |||
| eUint64,uint64_t) | eUint64,uint64_t) | |||
| for ( i = 0; i < NTstrings; ++i ) { | for ( i = 0; i < NTstrings; ++i ) { | |||
| /* test actual results int */ | /* test actual results int */ | |||
| err = TestR ( "stringai", fnvSuccess, | err = TestR ( "stringai", fnvSuccess, | |||
| skipping to change at line 5475 ¶ | skipping to change at line 5471 ¶ | |||
| FNV64stringin ( &e64Context, | FNV64stringin ( &e64Context, | |||
| teststring[i] + iLen/2 ) ); | teststring[i] + iLen/2 ) ); | |||
| if ( err ) break; | if ( err ) break; | |||
| err = TestR ( "resultab", fnvSuccess, | err = TestR ( "resultab", fnvSuccess, | |||
| FNV64result ( &e64Context, hash ) ); | FNV64result ( &e64Context, hash ) ); | |||
| if ( err ) break; | if ( err ) break; | |||
| TestNValue ( "incrementala", teststring[i], FNV64size, | TestNValue ( "incrementala", teststring[i], FNV64size, | |||
| hash, (uint8_t *)&FNV64svalues[i] ); | hash, (uint8_t *)&FNV64svalues[i] ); | |||
| /* now try testing file int */ | /* now try testing file int */ | |||
| err = TestR ( "fileafi", fnvSuccess, | err = TestR ( "fileafi", fnvSuccess, | |||
| FNV64INTfile ( | FNV64INTfile ( WriteTemp(teststring[i], iLen), | |||
| WriteTemp(teststring[i], iLen), | &eUint64 ) ); | |||
| &eUint64 ) | ||||
| ); | ||||
| if ( err ) break; | if ( err ) break; | |||
| TestNValue ( "filebfi", teststring[i], FNV64size, | TestNValue ( "filebfi", teststring[i], FNV64size, | |||
| (uint8_t *)&eUint64, | (uint8_t *)&eUint64, | |||
| (uint8_t *)&FNV64svalues[i] ); | (uint8_t *)&FNV64svalues[i] ); | |||
| /* now try testing file hash */ | /* now try testing file hash */ | |||
| TestFILEHash(FNV64file,FNV64svalues,FNV64size) | TestFILEHash(FNV64file,FNV64svalues,FNV64size) | |||
| } | } | |||
| ValueTestReport (); | ValueTestReport (); | |||
| } /* end Test64 */ | } /* end Test64 */ | |||
| skipping to change at line 5948 ¶ | skipping to change at line 5942 ¶ | |||
| # Makefile for fnv | # Makefile for fnv | |||
| # If you extract this file from RFC 9923, the five-character sequence | # If you extract this file from RFC 9923, the five-character sequence | |||
| # <TAB> below must be replaced with a tab (0x09) character. | # <TAB> below must be replaced with a tab (0x09) character. | |||
| explanation: | explanation: | |||
| <TAB>@echo Choose one of the following make targets: | <TAB>@echo Choose one of the following make targets: | |||
| <TAB>@echo make FNVhash -- test program | <TAB>@echo make FNVhash -- test program | |||
| <TAB>@echo make libfnv.a -- library you can use | <TAB>@echo make libfnv.a -- library you can use | |||
| <TAB>@echo make clean -- removes all of the built targets | <TAB>@echo make clean -- removes all of the built targets | |||
| SRC=FNV1024.c FNV128.c FNV256.c FNV32.c FNV512.c FNV64.c | SRC=FNV32.c FNV64.c FNV128.c FNV256.c FNV512.c FNV1024.c | |||
| HDR=FNV32.h FNV64.h FNV128.h FNV256.h FNV512.h FNV1024.h \ | HDR=FNV32.h FNV64.h FNV128.h FNV256.h FNV512.h FNV1024.h \ | |||
| <TAB>FNVErrorCodes.h FNVconfig.h fnv-private.h | <TAB>FNVconfig.h FNVErrorCodes.h fnv-private.h | |||
| OBJ=$(SRC:.c=.o) | OBJ=$(SRC:.c=.o) | |||
| CFLAGS=-Wall | CFLAGS=-Wall | |||
| AR=ar | AR=ar | |||
| ARFLAGS= rcs | ARFLAGS= rcs | |||
| FNVhash: libfnv.a main.c | FNVhash: libfnv.a main.c | |||
| <TAB>$(CC) $(CFLAGS) -o FNVhash main.c libfnv.a | <TAB>$(CC) $(CFLAGS) -o FNVhash main.c libfnv.a | |||
| libfnv.a: $(SRC) $(HDR) | libfnv.a: $(SRC) $(HDR) | |||
| <TAB>rm -f libfnv.a *.o | <TAB>rm -f libfnv.a *.o | |||
| skipping to change at line 5999 ¶ | skipping to change at line 5993 ¶ | |||
| [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
| 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
| May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| 10.2. Informative References | 10.2. Informative References | |||
| [BASIC] Diamond, W., "FNV32 PowerBASIC inline x86 assembler", | [BASIC] Diamond, W., "FNV32 PowerBASIC inline x86 assembler", | |||
| <http://www.isthe.com/chongo/tech/comp/fnv/ | <http://www.isthe.com/chongo/tech/comp/fnv/ | |||
| index.html#PowerBASIC>. | index.html#PowerBASIC>. | |||
| [BFDseq] Jethanandani, M., Agarwal, S., Mishra, A., Saxena, A., and | ||||
| A. DeKok, "Secure BFD Sequence Numbers", Work in Progress, | ||||
| Internet-Draft, draft-ietf-bfd-secure-sequence-numbers-09, | ||||
| 29 March 2022, <https://datatracker.ietf.org/doc/html/ | ||||
| draft-ietf-bfd-secure-sequence-numbers-09>. | ||||
| [calc] Bell, D. and L. Noll, "Calc - C-style arbitrary precision | [calc] Bell, D. and L. Noll, "Calc - C-style arbitrary precision | |||
| calculator", | calculator", | |||
| <http://www.isthe.com/chongo/tech/comp/calc/index.html>. | <http://www.isthe.com/chongo/tech/comp/calc/index.html>. | |||
| [Cohesia] Cohesia, "Cohesia website", <http://www.cohesia.com/>. | [Cohesia] Cohesia, "Cohesia website", <http://www.cohesia.com/>. | |||
| [deliantra] | [deliantra] | |||
| The Deliantra Team, "Deliantra MMORPG", 2016, | The Deliantra Team, "Deliantra MMORPG", 16 October 2022, | |||
| <http://www.deliantra.net/>. | <http://www.deliantra.net/>. | |||
| [fasmlab] Fasmlab, "Integrated Development Environments", | [fasmlab] Fasmlab, "Integrated Development Environments", | |||
| <https://sourceforge.net/projects/fasmlab/>. | <https://sourceforge.net/projects/fasmlab/>. | |||
| [FIPS202] NIST, "SHA-3 Standard: Permutation-Based Hash and | [FIPS202] NIST, "SHA-3 Standard: Permutation-Based Hash and | |||
| Extendable-Output Functions", FIPS PUB 202, | Extendable-Output Functions", FIPS PUB 202, | |||
| DOI 10.6028/NIST.FIPS.202, August 2015, | DOI 10.6028/NIST.FIPS.202, August 2015, | |||
| <https://nvlpubs.nist.gov/nistpubs/FIPS/ | <https://nvlpubs.nist.gov/nistpubs/FIPS/ | |||
| NIST.FIPS.202.pdf>. | NIST.FIPS.202.pdf>. | |||
| [flatassembler] | [flatassembler] | |||
| Grysztar, T., "flat assembler: Assembly language | Grysztar, T., "flat assembler: Assembly language | |||
| resources", 2025, <https://flatassembler.net/>. | resources", 2025, <https://flatassembler.net/>. | |||
| [FNV] Fowler-Noll-Vo, "FNV website", | [FNV] Fowler, G., Noll, L., and K. Vo, "FNV (Fowler/Noll/Vo)", | |||
| <http://www.isthe.com/chongo/tech/comp/fnv/index.html>. | <http://www.isthe.com/chongo/tech/comp/fnv/index.html>. | |||
| [Fortran] Fortran Standard Library, "A community driven standard | [Fortran] Fortran Standard Library, "A community driven standard | |||
| library for (modern) Fortran", | library for (modern) Fortran", | |||
| <https://stdlib.fortran-lang.org/>. | <https://stdlib.fortran-lang.org/>. | |||
| [FragCache] | [FragCache] | |||
| Weaver, E., "Improving Running Components at Twitter", | Weaver, E., "Improving Running Components at Twitter", | |||
| Slide 31, 2009, <https://www.slideshare.net/slideshow/ | Slide 31, 2009, <https://www.slideshare.net/slideshow/ | |||
| improving-running-components-at-twitter/1141786>. | improving-running-components-at-twitter/1141786>. | |||
| [FreeBSD] The Free BSD Project, "FreeBSD 4.3 Release Notes", 2025, | [FreeBSD] Baio, D. G., "FreeBSD 4.3 Release Notes (Last modified on | |||
| 21 February 2021)", The Free BSD Project, 2025, | ||||
| <https://www.freebsd.org/releases/4.3R/notes.html>. | <https://www.freebsd.org/releases/4.3R/notes.html>. | |||
| [FRET] McCarthy, M., "FRET: helping understand file formats", 19 | [FRET] McCarthy, M., "FRET: helping understand file formats", 19 | |||
| January 2006, <https://fret.sourceforge.net/>. | January 2006, <https://fret.sourceforge.net/>. | |||
| [GolfHash] Gliim LLC, "Golf Language Hash Tables", 2025, | ||||
| <https://golf-lang.com/new-hash.html>. | ||||
| [IEEE] Institute for Electrical and Electronics Engineers, "IEEE | [IEEE] Institute for Electrical and Electronics Engineers, "IEEE | |||
| website", <https://www.ieee.org/>. | website", <https://www.ieee.org/>. | |||
| [IEEE8021Qbp] | [IEEE8021Q-2022] | |||
| "Media Access Control (MAC) Bridges and Virtual Bridged | IEEE, "IEEE Standard for Local and Metropolitan Area | |||
| Local Area Networks - Equal Cost Multiple Path (ECMP)", | Networks--Bridges and Bridged Networks", | |||
| IEEE Std 802.1Qbp-2014, 7 April 2014. | DOI 10.1109/IEEESTD.2022.10004498, IEEE Std 802.1Q-2022, | |||
| December 2022, | ||||
| <https://ieeexplore.ieee.org/document/10004498>. | ||||
| [IEN137] Cohen, D., "On Holy Wars and A Plea For Peace", IEN 137, 1 | [IEN137] Cohen, D., "On Holy Wars and A Plea For Peace", IEN 137, 1 | |||
| April 1980, <https://www.rfc-editor.org/ien/ien137.txt>. | April 1980, <https://www.rfc-editor.org/ien/ien137.txt>. | |||
| [IPv6flow] Anderson, L., Brownlee, N., and B. Carpenter, "Comparing | [IPv6flow] Anderson, L., Brownlee, N., and B. E. Carpenter, | |||
| Hash Function Algorithms for the IPv6 Flow Label", | "Comparing Hash Function Algorithms for the IPv6 Flow | |||
| University of Auckland Department of Computer Science | Label", University of Auckland Department of Computer | |||
| Technical Report 2012-002, ISSN 1173-3500, March 2012, | Science Technical Report 2012-002, ISSN 1173-3500, March | |||
| <https://researchspace.auckland.ac.nz/bitstream/ | 2012, | |||
| handle/2292/13240/flowhashRep.pdf>. | <https://www.cs.auckland.ac.nz/~brian/flowhashRep.pdf>. | |||
| [ISAAC-Auth] | ||||
| DeKok, A., Jethanandani, M., Agarwal, S., Mishra, A., and | ||||
| J. Haas, "Meticulous Keyed ISAAC for BFD Optimized | ||||
| Authentication", Work in Progress, Internet-Draft, draft- | ||||
| ietf-bfd-secure-sequence-numbers-27, 16 October 2025, | ||||
| <https://datatracker.ietf.org/doc/html/draft-ietf-bfd- | ||||
| secure-sequence-numbers-27>. | ||||
| [LCN2] Noll, L. and C. Ferguson, "lcn2 / fnv", commit 953444c, 19 | [LCN2] Noll, L. and C. Ferguson, "lcn2 / fnv", commit 953444c, 19 | |||
| November 2025, <https://github.com/lcn2/fnv>. | November 2025, <https://github.com/lcn2/fnv>. | |||
| [Leprechaun] | [Leprechaun] | |||
| Sanmayce project, "Sanmayce project 'Underdog Way'", | Sanmayce project, "Sanmayce project 'Underdog Way'", | |||
| <http://www.sanmayce.com/Downloads/>. | <http://www.sanmayce.com/Downloads/>. | |||
| [libketama] | ||||
| Jones, R., "libketama: Consistent Hashing library for | ||||
| memcached clients", 10 April 2007, | ||||
| <https://www.metabrew.com/article/libketama-consistent- | ||||
| hashing-algo-memcached-clients>. | ||||
| [libsir] Lederman, R. and J. Johnson, "libsir logging library", | [libsir] Lederman, R. and J. Johnson, "libsir logging library", | |||
| commit 0ae0173, 3 December 2025, | commit 0ae0173, 3 December 2025, | |||
| <https://github.com/aremmell/libsir>. | <https://github.com/aremmell/libsir>. | |||
| [memcache] Dovgal, A., Joye, P., Radtke, H., Johansson, M., and T. | [memcache] Dovgal, A., Joye, P., Radtke, H., Johansson, M., and T. | |||
| Srnka, "PHP memcached extension", 30 April 2023, | Srnka, "PHP memcached extension", 30 April 2023, | |||
| <https://pecl.php.net/package/memcache>. | <https://pecl.php.net/package/memcache>. | |||
| [NCHF] Hayes, C. and D. Malone, "Questioning the Criteria for | [NCHF] Hayes, C. and D. Malone, "Questioning the Criteria for | |||
| Evaluating Non-Cryptographic Hash Functions", | Evaluating Non-Cryptographic Hash Functions", | |||
| skipping to change at line 6131 ¶ | skipping to change at line 6129 ¶ | |||
| [RFC7873] Eastlake 3rd, D. and M. Andrews, "Domain Name System (DNS) | [RFC7873] Eastlake 3rd, D. and M. Andrews, "Domain Name System (DNS) | |||
| Cookies", RFC 7873, DOI 10.17487/RFC7873, May 2016, | Cookies", RFC 7873, DOI 10.17487/RFC7873, May 2016, | |||
| <https://www.rfc-editor.org/info/rfc7873>. | <https://www.rfc-editor.org/info/rfc7873>. | |||
| [RFC8200] Deering, S. and R. Hinden, "Internet Protocol, Version 6 | [RFC8200] Deering, S. and R. Hinden, "Internet Protocol, Version 6 | |||
| (IPv6) Specification", STD 86, RFC 8200, | (IPv6) Specification", STD 86, RFC 8200, | |||
| DOI 10.17487/RFC8200, July 2017, | DOI 10.17487/RFC8200, July 2017, | |||
| <https://www.rfc-editor.org/info/rfc8200>. | <https://www.rfc-editor.org/info/rfc8200>. | |||
| [RimStone] Gliim LLC, "Golf Language Hash Tables", 2025, | ||||
| <https://rimstone-lang.com/>. | ||||
| [Smash] Emms, S., "Smash - find duplicate files super fast", 8 | ||||
| December 2024, <https://www.linuxlinks.com/smash-find- | ||||
| duplicate-files-super-fast/>. | ||||
| [twistylists] | [twistylists] | |||
| Zethmayr, D., "twistylists: A no-sort namespace engine; | Zethmayr, D., "twistylists: A no-sort namespace engine; | |||
| developers invited", 6 November 2012, | developers invited", 6 November 2012, | |||
| <https://twistylists.blogspot.com/>. | <https://twistylists.blogspot.com/>. | |||
| [Vely] Mijatovic, S., "Vely - general purpose framework", 26 | ||||
| October 2023, <https://www.linuxlinks.com/vely-general- | ||||
| purpose-framework/>. | ||||
| [Vortetty] "Raytracing for the gba", commit f8bf009, 26 February | ||||
| 2025, <https://github.com/Vortetty/gba-rtx>. | ||||
| Appendix A. Work Comparison with SHA-1 and SHA-256 | Appendix A. Work Comparison with SHA-1 and SHA-256 | |||
| This appendix provides a simplistic rough comparison of the level of | This appendix provides a simplistic rough comparison of the level of | |||
| effort required to compute FNV-1a, SHA-1 [RFC3174], and SHA-256 | effort required to compute FNV-1a, SHA-1 [RFC3174], and SHA-256 | |||
| [RFC6234] for short messages -- that is, those less than around 50 | [RFC6234] for short messages -- that is, those less than around 50 | |||
| bytes. Some CPUs may have special instructions or other hardware to | bytes. Some CPUs may have special instructions or other hardware to | |||
| accelerate certain cryptographic operations, so if performance is | accelerate certain cryptographic operations, so if performance is | |||
| particularly important for an application, benchmarking on the target | particularly important for an application, benchmarking on the target | |||
| platform would be appropriate. | platform would be appropriate. | |||
| skipping to change at line 6168 ¶ | skipping to change at line 6166 ¶ | |||
| although almost all computer uses apply them to an integer number of | although almost all computer uses apply them to an integer number of | |||
| bytes. They both process blocks of 512 bits (64 bytes), and we | bytes. They both process blocks of 512 bits (64 bytes), and we | |||
| estimate the effort involved in processing a full block. There is | estimate the effort involved in processing a full block. There is | |||
| some overhead per message to indicate message termination and size. | some overhead per message to indicate message termination and size. | |||
| Assuming that the message is an even number of bytes, this overhead | Assuming that the message is an even number of bytes, this overhead | |||
| would be 9 bytes for SHA-1 and 17 bytes for SHA-256. So, assuming | would be 9 bytes for SHA-1 and 17 bytes for SHA-256. So, assuming | |||
| that the message with that overhead fits into one block, the message | that the message with that overhead fits into one block, the message | |||
| would be up to 55 bytes for SHA-1 or up to 47 bytes for SHA-256. | would be up to 55 bytes for SHA-1 or up to 47 bytes for SHA-256. | |||
| SHA-1 is a relatively weak cryptographic hash function producing a | SHA-1 is a relatively weak cryptographic hash function producing a | |||
| 160-bit hash. It has been partially broken [RFC6194]. Ignoring SHA- | 160-bit hash. It has been substantially broken [RFC6194]. Ignoring | |||
| 1's initial setup, transfer of control, and conditional tests, but | SHA-1's initial setup, transfer of control, and conditional tests, | |||
| counting all logical and arithmetic operations, including counting | but counting all logical and arithmetic operations, including | |||
| indexing as an addition, SHA-1 requires 1,744 operations per 64-byte | counting indexing as an addition, SHA-1 requires 1,744 operations per | |||
| block or 31.07 operations per byte for a message of 55 bytes. By | 64-byte block or 31.07 operations per byte for a message of 55 bytes. | |||
| this rough measure, it is a little over 15.5 times the effort of FNV. | By this rough measure, it is a little over 15.5 times the effort of | |||
| FNV. | ||||
| SHA-256 is, at the time of publication, considered to be a stronger | SHA-256 is, at the time of publication, considered to be a stronger | |||
| cryptographic hash function than SHA-1. Ignoring SHA-256's initial | cryptographic hash function than SHA-1. Ignoring SHA-256's initial | |||
| setup, transfer of control, and conditional tests, but counting all | setup, transfer of control, and conditional tests, but counting all | |||
| logical and arithmetic operations, SHA-1 requires 2,058 operations | logical and arithmetic operations, SHA-1 requires 2,058 operations | |||
| per 64-byte block or 48.79 operations per byte for a message of 47 | per 64-byte block or 48.79 operations per byte for a message of 47 | |||
| bytes. By this rough measure, it is over 24 times the effort of FNV. | bytes. By this rough measure, it is over 24 times the effort of FNV. | |||
| However, FNV is commonly used for short inputs, so doing a comparison | However, FNV is commonly used for short inputs, so doing a comparison | |||
| of such inputs is relevant. Using the above comparison method, for | of such inputs is relevant. Using the above comparison method, for | |||
| End of changes. 137 change blocks. | ||||
| 294 lines changed or deleted | 293 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. | ||||