View mode: basic / threaded / horizontal-split · Log in · Help
October 11, 2004
Re: ubyte to string conversion (md5)
"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
October 11, 2004
Re: ubyte to string conversion (md5)
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
October 11, 2004
Re: ubyte to string conversion (md5)
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/
October 11, 2004
Re: ubyte to string conversion (md5)
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/
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home