Please help rescue me from my ignorance. ;)

J

John

Hi,

In a nutshell, why am I getting the results I am getting? I would have
expected a call to method1( n) to return an 'n' length string.

At first I thought it was a problem in my function, but after finding an
article showing how to do the salt, I noticed, they had basically the same
code as me. So obviously, I'm so lost, I didn't even know I was lost.

Can somebody please direct me to an online article explaining what I don't
understand.

Thanks

-- class --
class Class1
{
static void Main(string[] args)
{
for( int len = 10; len <30; len++)
{
string s = Class1.Method1( len);
Console.Out.WriteLine( "Method1({0}) results : {1} and len={2}", len,
s, s.Length);
}

Console.Out.WriteLine( "press enter to exit");
Console.In.Read();
}

// from internet
public static string Method1( int saltLen)
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] buff = new byte[saltLen];
rng.GetBytes(buff);
return Convert.ToBase64String(buff);
}
}

-- output --
Method1(10) results : vQERIYXmGC7K/w== and len=16
Method1(11) results : RaA9HXz31CjigAg= and len=16
Method1(12) results : g3CbTZskaCCUjFDU and len=16
Method1(13) results : GInzz5LJpUXkOnaJ4Q== and len=20
Method1(14) results : UyTlZoOACCSTswc6IBI= and len=20
Method1(15) results : 8bJ3AvmJRqZy2Sw3wy+8 and len=20
Method1(16) results : 9PeRWzfrhGjzl27WOa1iyw== and len=24
Method1(17) results : bUHbbeLpLFQrn/RDzf01Ny0= and len=24
Method1(18) results : 3ZBiY++Vcd8reojolOmfPpfg and len=24
Method1(19) results : 3ToL3JDa9naqJrHlQQm/kUg8Vg== and len=28
Method1(20) results : OINljarFIM2uAypPLzMl6qfLN60= and len=28
Method1(21) results : R3PGSjLnhTrAxRrUVFXpL1DCrkNH and len=28
Method1(22) results : L/XiRyRWkU9+GrQnGkB5hzvtgA5LPQ== and len=32
Method1(23) results : YSwyvS2X5C7I0zxdNL8nSa7h/6T1fAM= and len=32
Method1(24) results : kHkaClhr+XutyhFUX0j3I/Hu9iko0Cvm and len=32
Method1(25) results : a5wFU26nON85AjkVQ+2A+1g+NqTq4UCuzw== and len=36
Method1(26) results : 1gPsznq6t4x1ME0ohfiZ2FtV0qBUWfbOtzE= and len=36
Method1(27) results : 03gkSPvg9oLS7u8Ic3XsGVZ90+R9WmF0uuKz and len=36
Method1(28) results : SMS+B8+xBz2xapyrg572Awrf0W9jydbExXTs+g== and len=40
Method1(29) results : m+LkKfPVOaJi7J2giJpDqFGEJoxu4WgLBK/qyC4= and len=40
press enter to exit
 
F

Francisco Padron

When using Base64, a byte may be converted to more than one character, after
all base64 only uses "readable" characters. The relationship between the
length of the byte array and the length of the string depends on the
contents of the byte array.
 
J

Jon Skeet [C# MVP]

John said:
In a nutshell, why am I getting the results I am getting? I would have
expected a call to method1( n) to return an 'n' length string.

At first I thought it was a problem in my function, but after finding an
article showing how to do the salt, I noticed, they had basically the same
code as me. So obviously, I'm so lost, I didn't even know I was lost.

Can somebody please direct me to an online article explaining what I don't
understand.

It sounds like it's what Convert.ToBase64String does that's the
problem. It Base64 encodes an arbitrary byte array - and the results of
Base64 encoding are always 4/3 * size of original data, rounded up to
the nearest 4, in characters.

Now, what exactly are you trying to do? If you just need the salt as a
binary value and you're encoding it for transport, that's fine -
decoding it from base64 will give you the right results. If, however,
you want a random string of a given length (and from a given set of
characters) this isn't the best way of doing it.
 
J

John

Jon Skeet said:
Now, what exactly are you trying to do? If you just need the salt as a
binary value and you're encoding it for transport, that's fine -
decoding it from base64 will give you the right results. If, however,
you want a random string of a given length (and from a given set of
characters) this isn't the best way of doing it.

Thanks Jon,

Basically, I am trying to create a salt-password secenario similar to the
one in the Salting a Hash section of
http://www.dotnetjunkies.com/Tutorial/77D4AFDC-585D-4539-A364-30028327FF14.dcik

If that's not the best way to create a random string with a given length,
what is?

Thanks again,
John
 
J

Jon Skeet [C# MVP]

John said:
Basically, I am trying to create a salt-password secenario similar to the
one in the Salting a Hash section of
http://www.dotnetjunkies.com/Tutorial/77D4AFDC-585D-4539-A364-30028327FF14.dcik

If that's not the best way to create a random string with a given length,
what is?

Well, something like:

[ThreadStatic]
static Random random;

public static string GenerateRandomString (string characters,
int length)
{
if (random==null)
{
// Help to give each thread a different RNG seed
random = new Random(Environment.TickCount ^
Thread.CurrentThread.GetHashCode());
}

char[] ret = new char[length];
for (int i=0; i < length; i++)
{
ret = characters[random.Next(characters.Length)];
}
return new string (ret);
}

You pass in the character set you want to use, and the length.
Considerably more flexible than using base64.
 
J

Jon Skeet [C# MVP]

Jon Skeet said:
Well, something like:

<snip>

Having had a closer look at the article, it's suggesting using
RNGCryptoServiceProvider for extra security. If this is important to
you but you still want the flexibility of the method I showed, you can
reasonably easily change my code to use the bytes provided by the
RNGCryptoServiceProvider as indexes into the character set rather than
using System.Random. (The use of a thread local will reduce the risk of
getting identical salts anyway, but RNGCryptoServiceProvider is
probably still safer.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top