digitalmars.D - ubyte to string conversion (md5)
- "Asaf Karagila" <kas1 netvision.net.il> Oct 09 2004
- "Ben Hinkle" <bhinkle mathworks.com> Oct 09 2004
- "Asaf Karagila" <kas1 netvision.net.il> Oct 09 2004
- Regan Heath <regan netwin.co.nz> Oct 10 2004
- "Asaf Karagila" <kas1 netvision.net.il> Oct 10 2004
- Sjoerd van Leent <svanleent wanadoo.nl> Oct 11 2004
- "Asaf Karagila" <kas1 netvision.net.il> Oct 11 2004
- Sjoerd van Leent <svanleent wanadoo.nl> Oct 11 2004
- "Asaf Karagila" <kas1 netvision.net.il> Oct 11 2004
- Burton Radons <burton-radons smocky.com> Oct 11 2004
- "Asaf Karagila" <kas1 netvision.net.il> Oct 11 2004
- Sjoerd van Leent <svanleent wanadoo.nl> Oct 11 2004
- Regan Heath <regan netwin.co.nz> Oct 11 2004
- Regan Heath <regan netwin.co.nz> Oct 11 2004
well, i'm kinda stuck.. i've done those things before, and for some reason, they won't work here.. i'm trying to convert an MD5 digest from std.md5 (ubyte[16]) into a string (char[]) i need it for internal usage, so using printDigest is useless for me, unless there is a way i can print it into a string.. i tired (fuitily i must say) several ways of converting the bytes into chars, none worked. does anyone have any code for that, or some tips for me ? Cheers, Asaf
Oct 09 2004
"Asaf Karagila" <kas1 netvision.net.il> wrote in message news:ck9s27$1b4a$1 digitaldaemon.com...well, i'm kinda stuck.. i've done those things before, and for some reason, they won't work here.. i'm trying to convert an MD5 digest from std.md5 (ubyte[16]) into a string (char[]) i need it for internal usage, so using printDigest is useless for me,
there is a way i can print it into a string.. i tired (fuitily i must say) several ways of converting the bytes into chars, none worked. does anyone have any code for that, or some tips for me ? Cheers, Asaf
do you mean something like: import std.string; import std.stdio; ubyte[] x = [10, 20, 30]; int main() { char[] y; foreach(ubyte n;x) y ~= toString(n) ~ " "; writefln(y); return 0; }
Oct 09 2004
"Ben Hinkle" <bhinkle mathworks.com> wrote in message news:cka2o8$1ep3$1 digitaldaemon.com..."Asaf Karagila" <kas1 netvision.net.il> wrote in message news:ck9s27$1b4a$1 digitaldaemon.com...well, i'm kinda stuck.. i've done those things before, and for some reason, they won't work here.. i'm trying to convert an MD5 digest from std.md5 (ubyte[16]) into a string (char[]) i need it for internal usage, so using printDigest is useless for me,
there is a way i can print it into a string.. i tired (fuitily i must say) several ways of converting the bytes into chars, none worked. does anyone have any code for that, or some tips for me ? Cheers, Asaf
do you mean something like: import std.string; import std.stdio; ubyte[] x = [10, 20, 30]; int main() { char[] y; foreach(ubyte n;x) y ~= toString(n) ~ " "; writefln(y); return 0; }
thats a cool routine, but its not exactly what i am looking for, it gives out a decimal output, what i need is actually a 128bit hex number output..
Oct 09 2004
On Sun, 10 Oct 2004 01:26:51 +0200, Asaf Karagila <kas1 netvision.net.il> wrote:well, i'm kinda stuck.. i've done those things before, and for some reason, they won't work here.. i'm trying to convert an MD5 digest from std.md5 (ubyte[16]) into a string (char[]) i need it for internal usage, so using printDigest is useless for me, unless there is a way i can print it into a string.. i tired (fuitily i must say) several ways of converting the bytes into chars, none worked. does anyone have any code for that, or some tips for me ?
Try this... template hexStringT(T) { char[] hexStringT(T d) { char[] result; if (d.length != 0) { typeof(d[0]) u; uint sz = u.sizeof*2; uint ndigits = 0; result = new char[sz*d.length]; for(int i = d.length-1; i >= 0; i--) { u = d[i]; for(; u; u /= 16) { result[result.length-1-ndigits] = hexdigits[u & 15]; ndigits++; } for(; ndigits < (d.length-i)*sz; ndigits++) result[result.length-1-ndigits] = '0'; } } return result; } } char[] toHexString(ubyte[] array) { return hexStringT!(typeof(array))(array); } char[] toHexString(ulong[] array) { return hexStringT!(typeof(array))(array); } char[] toHexString(uint[] array) { return hexStringT!(typeof(array))(array); } The above code is from my library of hashing routines in the Deimos library which you can find here: http://www.dsource.org/projects/deimos/ Deimos is an open source library to which anyone can contribute. You can use the "Browse SVN Repository for Deimos" link to have a look at the other source files, the hashing routines are here: http://svn.dsource.org/svn/projects/deimos/trunk/etc/crypto/hash/ Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Oct 10 2004
thanks for the code,
its a bit over my level at the moment, and i don't like using code i can't
understand..
so i'm not sure if i'll use it,
as well, i managed to sort something out.. its almost perfect as well..
foreach(ubyte u;array)
myString ~= std.string.format("%2X",u);
it gives me out a pretty good result, only its sticking a 'b' on the end, i
don't know why..
anyone got a clue about that ?
Cheers,
Asaf
Oct 10 2004
Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
Oct 11 2004
"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckdp2m$15id$1 digitaldaemon.com...Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
yeah, it doesn't look flawed either, so maybe the buffer allocated for the char[] i have is already used ? if so, is there a way to initialize the array to be clear, and to clean the memory its using ? Cheers, Asaf
Oct 11 2004
Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckdp2m$15id$1 digitaldaemon.com...Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
yeah, it doesn't look flawed either, so maybe the buffer allocated for the char[] i have is already used ? if so, is there a way to initialize the array to be clear, and to clean the memory its using ? Cheers, Asaf
Initialize the array to an empty array. This could be done using an empty array or using the init property of the current array: char[] s; s = s.init; this should work as expected. Regards, Sjoerd
Oct 11 2004
"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckebb5$1mkb$1 digitaldaemon.com...Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckdp2m$15id$1 digitaldaemon.com...Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
yeah, it doesn't look flawed either, so maybe the buffer allocated for the char[] i have is already used ? if so, is there a way to initialize the array to be clear, and to clean the memory its using ? Cheers, Asaf
Initialize the array to an empty array. This could be done using an empty array or using the init property of the current array: char[] s; s = s.init; this should work as expected. Regards, Sjoerd
char[] MD5; MD5.init; foreach(ubyte u;di) MD5 ~= std.string.format("%2X",u); printf(MD5); the output is : "9ADD3AF83DD9DAAA75BDF5CE4E476CBCb" i don't know where does this 'b' is coming from, and i would like to remove it.. weird. Cheers, Asaf
Oct 11 2004
Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckebb5$1mkb$1 digitaldaemon.com...Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckdp2m$15id$1 digitaldaemon.com...Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
yeah, it doesn't look flawed either, so maybe the buffer allocated for the char[] i have is already used ? if so, is there a way to initialize the array to be clear, and to clean the memory its using ? Cheers, Asaf
Initialize the array to an empty array. This could be done using an empty array or using the init property of the current array: char[] s; s = s.init; this should work as expected. Regards, Sjoerd
char[] MD5; MD5.init; foreach(ubyte u;di) MD5 ~= std.string.format("%2X",u); printf(MD5); the output is : "9ADD3AF83DD9DAAA75BDF5CE4E476CBCb" i don't know where does this 'b' is coming from, and i would like to remove it.. weird.
http://www.digitalmars.com/d/faq.html#printf
Oct 11 2004
"Asaf Karagila" <kas1 netvision.net.il> wrote in message news:ckecsq$1o26$1 digitaldaemon.com...char[] MD5; MD5.init; foreach(ubyte u;di) MD5 ~= std.string.format("%2X",u); printf(MD5); the output is : "9ADD3AF83DD9DAAA75BDF5CE4E476CBCb" i don't know where does this 'b' is coming from, and i would like to remove it.. weird. Cheers, Asaf
well, as i suspected, the problem resides within the MD5 string space, nothing helped, its probably a bug in the implementation, when i made an addition to the code char[32] md5string; for (int i=0;i<MD5.length;i++) md5string[i]=MD5[i]; the 'b' on the end of the MD5 string was gone.. i guess that solves my problem. but i think its ought a deeper check, i'll do my best to debug it in low level.. if i'll have something concrete, i'll post it back. Cheers, Asaf
Oct 11 2004
Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckebb5$1mkb$1 digitaldaemon.com...Asaf Karagila wrote:"Sjoerd van Leent" <svanleent wanadoo.nl> wrote in message news:ckdp2m$15id$1 digitaldaemon.com...Asaf Karagila wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand.. so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u); it gives me out a pretty good result, only its sticking a 'b' on the end, i don't know why.. anyone got a clue about that ? Cheers, Asaf
I don't quite see what the problem is. If I run the following code: import std.stdio; import std.string; int main (char[][] args) { char[] s; const static ubyte[] array = [ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF ]; foreach(ubyte u; array) { s ~= format("%2X", u); } writefln(s); // writes: 0 1 2 3 4 5 6 7 8 9 A B C D E F return 0; } It does print the values as it is supposed to do Regards, Sjoerd
yeah, it doesn't look flawed either, so maybe the buffer allocated for the char[] i have is already used ? if so, is there a way to initialize the array to be clear, and to clean the memory its using ? Cheers, Asaf
Initialize the array to an empty array. This could be done using an empty array or using the init property of the current array: char[] s; s = s.init; this should work as expected. Regards, Sjoerd
char[] MD5; MD5.init; foreach(ubyte u;di) MD5 ~= std.string.format("%2X",u); printf(MD5); the output is : "9ADD3AF83DD9DAAA75BDF5CE4E476CBCb" i don't know where does this 'b' is coming from, and i would like to remove it.. weird. Cheers, Asaf
Ah there is the problem, if you look close to my code, you'll notice that I use writefln instead of printf. Printf only knows standard C string conventions, which isn't used by D. You should use the writef and writefln of the sts.stdio module instead. Regards, Sjoerd
Oct 11 2004
On Mon, 11 Oct 2004 19:46:26 +0200, Sjoerd van Leent <svanleent wanadoo.nl> wrote:the output is : "9ADD3AF83DD9DAAA75BDF5CE4E476CBCb" i don't know where does this 'b' is coming from, and i would like to remove it.. weird. Cheers, Asaf
Ah there is the problem, if you look close to my code, you'll notice that I use writefln instead of printf. Printf only knows standard C string conventions, which isn't used by D. You should use the writef and writefln of the sts.stdio module instead.
Sjoerd is right :) You can still use printf if you like, see the link Burton gave: http://www.digitalmars.com/d/faq.html#printf eg. printf("%.*s",MD5); Basically, a D char[] is a struct sorta like so struct char { int length; void* data; } so the above is a little bit of an evil hack, causing printf to grab the length from the D char and print only the right amount of data. a D char[]'s data does not contain the C trailing NULL character which signals the end of the string. D will auto-magically cast a D char to a C char, but, it does not add a trailing NULL. To add a trailing NULL try: printf(toStringZ(MD5)); As the signature for printf is: int printf(char *format, ...); D is converting the D char[] to a char *, but not adding a null. As printf keeps going till it finds a NULL, it's simply luck that it stops where it does. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Oct 11 2004
On Mon, 11 Oct 2004 07:30:41 +0200, Asaf Karagila <kas1 netvision.net.il> wrote:thanks for the code, its a bit over my level at the moment, and i don't like using code i can't understand..
Then allow me to elucidate... It's not too complex if you break it down into parts. It's a generic version of this: const char[16] hexdigits = "0123456789ABCDEF"; char[] hexStringT(ubyte[] d) { char[] result; /* No point converting an empty array now is there? */ if (d.length != 0) { ubyte u; uint sz = u.sizeof*2; /* number of chars required to represent one 'u' */ uint ndigits = 0; /* pre-allocate space required. */ result = new char[sz*d.length]; /* start at end of resulting string, loop back to start. */ for(int i = d.length-1; i >= 0; i--) { /*this loop takes the remainder of u/16, uses it as an index into the hexdigits array, then does u/16, repeating till u == 0 */ u = d[i]; for(; u; u /= 16) { /* you can use u & 15 or u % 16 below both give you the remainder of u/16 */ result[result.length-1-ndigits] = hexdigits[u & 15]; ndigits++; } /* Pad each value with 0's */ for(; ndigits < (d.length-i)*sz; ndigits++) result[result.length-1-ndigits] = '0'; } } return result; } which is very similar to the functions in std.string, i.e. char[] toString(uint u) { char[uint.sizeof * 3] buffer; int ndigits; char c; char[] result; ndigits = 0; if (u < 10) // Avoid storage allocation for simple stuff result = digits[u .. u + 1]; else { while (u) { c = (u % 10) + '0'; u /= 10; ndigits++; buffer[buffer.length - ndigits] = c; } result = new char[ndigits]; result[] = buffer[buffer.length - ndigits .. buffer.length]; } return result; }so i'm not sure if i'll use it, as well, i managed to sort something out.. its almost perfect as well.. foreach(ubyte u;array) myString ~= std.string.format("%2X",u);
yeah, that works, I believe my methods is more efficient because: - yours is appending, which causes string reallocations. - yours is calling a complex function 'format' for each ubyte. that said, the difference is probably negligible unless you're using it a lot. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Oct 11 2004









"Asaf Karagila" <kas1 netvision.net.il> 