Thread overview
[Issue 11757] New: toHexString doesn't support dynamic array
Dec 17, 2013
Mathias LANG
Dec 17, 2013
Mathias LANG
December 17, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=11757

           Summary: toHexString doesn't support dynamic array
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody@puremagic.com
        ReportedBy: pro.mathias.lang@gmail.com


--- Comment #0 from Mathias LANG <pro.mathias.lang@gmail.com> 2013-12-17 04:23:30 PST ---
import std.digest.md;
import std.digest.sha;

ubyte[]    hmac_md5(ubyte[] key, string msg)
{
    immutable auto blocksize = 64;
    if (key.length > blocksize)
        key = md5Of(key);
    if (key.length < blocksize)
        key.length = blocksize;
    ubyte[blocksize] okp = 0x5c;
    ubyte[blocksize] ikp = 0x36;
    for (size_t i = 0; i < blocksize; ++i)
        okp[i] ^= key[i];
    for (size_t i = 0; i < blocksize; ++i)
        ikp[i] ^= key[i];
    return md5Of(okp ~ md5Of(ikp ~ cast(ubyte[])(msg)));
}
ubyte[]    hmac_md5(string key, string msg)
{
    return hmac_md5(cast(ubyte[])(key), msg);
}

unittest {
    auto md5hmac = hmac_md5("key", "The quick brown fox jumps over the lazy
dog");
    assert(toHexString(md5hmac) == "80070713463E7749B90C2DC24911E275");
}


This unittest will fail (toHexString returns
'E0166C00000000000000000000000000'), but if you replace ubyte[] with ubyte[16]
-or auto-, it'll pass.
DMD 2.064.2

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 17, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=11757


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #1 from bearophile_hugs@eml.cc 2013-12-17 04:44:30 PST ---
(In reply to comment #0)

>     return hmac_md5(cast(ubyte[])(key), msg);

Don't use cast() unless you know what you are doing.


> 'E0166C00000000000000000000000000'), but if you replace ubyte[] with ubyte[16] -or auto-, it'll pass.

One advantage of the current design of toHexString() is that it can't fail,
because the type system makes its usage safe and correct for most situations.
(Unless you use cast() randomly).

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 17, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=11757


Mathias LANG <pro.mathias.lang@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID


--- Comment #2 from Mathias LANG <pro.mathias.lang@gmail.com> 2013-12-17 05:32:59 PST ---
(In reply to comment #1)
> (In reply to comment #0)
> 
> >     return hmac_md5(cast(ubyte[])(key), msg);
> 
> Don't use cast() unless you know what you are doing.
> 
> 
> > 'E0166C00000000000000000000000000'), but if you replace ubyte[] with ubyte[16] -or auto-, it'll pass.
> 
> One advantage of the current design of toHexString() is that it can't fail,
> because the type system makes its usage safe and correct for most situations.
> (Unless you use cast() randomly).

Fair enough. I'm just a beginner, with a C[++] background, so keeping in mind
that string == immutable(char[]), chars are UTF-8, and my string is pure ASCII,
I "just" expected it to work.
I'll close this as invalid so, but I wouldn't be against an enlightment of
what's going on (and how to convert a string to an ubyte safely).
Thanks bearophile !

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 17, 2013
https://d.puremagic.com/issues/show_bug.cgi?id=11757



--- Comment #3 from bearophile_hugs@eml.cc 2013-12-17 07:09:23 PST ---
(In reply to comment #2)

> Fair enough. I'm just a beginner, with a C[++] background, so keeping in mind
> that string == immutable(char[]), chars are UTF-8, and my string is pure ASCII,
> I "just" expected it to work.
> I'll close this as invalid so, but I wouldn't be against an enlightment of
> what's going on (and how to convert a string to an ubyte safely).

In D fixed-sized arrays are values. ubyte[16] is a value, it's 16 unsigned bytes.

A string is a struct that contains two words: a length and a pointer to a series of immutable chars.

When you have similar doubts or questions I suggest you to ask them in the D.learn newsgroup.

Your D code has several problems. This is a fist try at improving your code, but some small problems still need to be fixed:


import std.digest.md, std.digest.sha, std.string;

enum size_t blockSize = 64;
enum size_t digestSize = 16;

ubyte[digestSize] hmacMD5(in ubyte[blockSize] key, in ubyte[] msg)
pure nothrow {
    ubyte[key.length] okp = 0x5c;
    okp[] ^= key[];
    ubyte[key.length] ikp = 0x36;
    ikp[] ^= key[];

    // Heap allocations here:
    return md5Of(okp ~ md5Of(ikp ~ msg));
}

ubyte[digestSize] hmacMD5(in string key, in string msg)
pure nothrow {
    ubyte[blockSize] key2;

    if (key.length > blockSize)
        key2[0 .. digestSize] = key.md5Of;
    else if (key.length < blockSize)
        key2[0 .. key.length] = key[].representation;

    return hmacMD5(key2, msg.representation);
}

void main() {
    immutable r = hmacMD5("key", "The quick brown fox jumps over the lazy
dog");
    assert(r.toHexString == "80070713463E7749B90C2DC24911E275");
}

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------