std.digest

This module describes the digest APIs used in Phobos. All digests follow these APIs. Additionally, this module contains useful helper methods which can be used with every digest type.

APIs: There are two APIs for digests: The template API and the OOP API. The template API uses structs and template helpers like isDigest. The OOP API implements digests as classes inheriting the Digest interface. All digests are named so that the template API struct is called "x" and the OOP API class is called "xDigest". For example we have MD5 <--> MD5Digest, CRC32 <--> CRC32Digest, etc.

The template API is slightly more efficient. It does not have to allocate memory dynamically, all memory is allocated on the stack. The OOP API has to allocate in the finish method if no buffer was provided. If you provide a buffer to the OOP APIs finish function, it doesn't allocate, but the Digest classes still have to be created using new which allocates them using the GC.

The OOP API is useful to change the digest function and/or digest backend at 'runtime'. The benefit here is that switching e.g. Phobos MD5Digest and an OpenSSLMD5Digest implementation is ABI compatible.

If just one specific digest type and backend is needed, the template API is usually a good fit. In this simplest case, the template API can even be used without templates: Just use the "x" structs directly.

License

Boost License 1.0.

Authors

Johannes Pfau

Source: std/digest/package.d

CTFE: Digests do not work in CTFE

TODO: Digesting single bits (as opposed to bytes) is not implemented. This will be done as another template constraint helper (hasBitDigesting!T) and an additional interface (BitDigest)

Types 4

interfaceDigest

This describes the OOP API. To understand when to use the template API and when to use the OOP API, see the module documentation at the top of this page.

The Digest interface is the base interface which is implemented by all digests.

Note

A Digest implementation is always an OutputRange
Methods
void put(scope const(ubyte)[] data...) @trusted nothrowUse this to feed the digest with data. Also implements the isOutputRange interface for `ubyte` and `const(ubyte)[]`.
void reset() @trusted nothrowResets the internal state of the digest. Note: finish calls this internally, so it's not necessary to call `reset` manually after a call to finish.
size_t length() @trusted nothrow @property const;This is the length in bytes of the hash value which is returned by finish. It's also the required size of a buffer passed to finish.
ubyte[] finish() @trusted nothrowThe finish function returns the hash value. It takes an optional buffer to copy the data into. If a buffer is passed, it must be at least length bytes big.
ubyte[] finish(ubyte[] buf) nothrowditto
ubyte[] digest(scope const(void[])[] data...) @trusted nothrowThis is a convenience function to calculate the hash of a value using the OOP API.
enumOrder : bool
increasing
decreasing
classWrapperDigest(T) : Digest if (isDigest!T)

Wraps a template API hash struct into a Digest interface. Modules providing digest implementations will usually provide an alias for this template (e.g. MD5Digest, SHA1Digest, ...).

Fields
T _digest
Methods
void put(scope const(ubyte)[] data...) @trusted nothrowUse this to feed the digest with data. Also implements the isOutputRange interface for `ubyte` and `const(ubyte)[]`.
void reset() @trusted nothrowResets the internal state of the digest. Note: finish calls this internally, so it's not necessary to call `reset` manually after a call to finish.
size_t length() @trusted nothrow @property const pureThis is the length in bytes of the hash value which is returned by finish. It's also the required size of a buffer passed to finish.
ubyte[] finish(ubyte[] buf) nothrowThe finish function returns the hash value. It takes an optional buffer to copy the data into. If a buffer is passed, it must have a length at least length bytes.
ubyte[] finish() @trusted nothrowditto
Constructors
this()Initializes the digest.
private structHexStringDecoder(String) if (isSomeString!String)
Fields
String hex
ubyte front
bool empty
Methods
void popFront()
typeof(this) save()
size_t length() const
Constructors
this(String hex)

Functions 16

fnDigestType!Hash digest(Hash, Range)(auto ref Range range) if (!isArray!Range && isDigestibleRange!Range)This is a convenience function to calculate a hash using the template API. Every digest passing the isDigest test can be used with this function.
fnDigestType!Hash digest(Hash, T...)(scope const T data) if (allSatisfy!(isArray, typeof(data)))This overload of the digest function handles arrays.
fnchar[digestLength!(Hash) * 2] hexDigest(Hash, Order order = Order.increasing, Range)(ref Range range) if (!isArray!Range && isDigestibleRange!Range)This is a convenience function similar to digest, but it returns the string representation of the hash. Every digest passing the isDigest test can be used with this function.
fnchar[digestLength!(Hash) * 2] hexDigest(Hash, Order order = Order.increasing, T...)(scope const T data) if (allSatisfy!(isArray, typeof(data)))This overload of the hexDigest function handles arrays.
fnHash makeDigest(Hash)()This is a convenience function which returns an initialized digest, so it's not necessary to call start manually.
fnchar[num * 2] toHexString(Order order = Order.increasing, size_t num, LetterCase letterCase = LetterCase.upper)(const ubyte[num] digest)Used to convert a hash value (a static or dynamic array of ubytes) to a string. Can be used with the OOP and with the template API.
fnchar[num * 2] toHexString(LetterCase letterCase, Order order = Order.increasing, size_t num)(in ubyte[num] digest)ditto
fnstring toHexString(Order order = Order.increasing, LetterCase letterCase = LetterCase.upper)(in ubyte[] digest)ditto
fnstring toHexString(LetterCase letterCase, Order order = Order.increasing)(in ubyte[] digest)ditto
fnT[N] asArray(size_t N, T)(ref T[] source, string errorMsg = "") ref
private fnvoid toHexStringImpl(Order order, LetterCase letterCase, BB, HB)(scope const ref BB byteBuffer, ref HB hexBuffer){
fnbool secureEqual(R1, R2)(R1 r1, R2 r2) if (isInputRange!R1 && isInputRange!R2 && !isInfinite!R1 && !isInfinite!R2 && (isIntegral!(ElementEncodingType!R1) || isSomeChar!(ElementEncodingType!R1)) && !is(CommonType!(ElementEncodingType!R1, ElementEncodingType!R2) == void))Securely compares two digest representations while protecting against timing attacks. Do not use `==` to compare digest representations.
fnbool isHexString(String)(String hex) if (isSomeString!String) @safe pure nothrow @nogcValidates a hex string.
fnauto fromHexStringAsRange(String)(String hex) if (isSomeString!String) @safe pure nothrow @nogcConverts a hex text string to a range of bytes.
fnubyte[] fromHexString(String)(String hex) if (isSomeString!String) @safe pureConverts a hex text string to a range of bytes.
private fnubyte hexDigitToByte(dchar hexDigit) @safe pure nothrow @nogc

Templates 6

tmplisDigest(T)

Use this to check if a type is a digest. See ExampleDigest to see what a type must provide to pass this check.

Note

This is very useful as a template constraint (see examples)

BUGS:

  • Does not yet verify that put takes scope parameters.
  • Should check that finish() returns a ubyte[num] array
tmplDigestType(T)

Use this template to get the type which is returned by a digest's finish method.

tmplhasPeek(T)

Used to check if a digest supports the peek method. Peek has exactly the same function signatures as finish, but it doesn't reset the digest's internal state.

Note

  • This is very useful as a template constraint (see examples)
  • This also checks if T passes isDigest
tmplhasBlockSize(T) if (isDigest!T)

Checks whether the digest has a blockSize member, which contains the digest's internal block size in bits. It is primarily used by HMAC.

tmplisDigestibleRange(Range)
tmpldigestLength(T) if (isDigest!T)