- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
I call plagiarism! I wrote a password generating function in PHP that was extremely similar to th----
Er, nothing. I didn't. Just kidding. I'd never write such bad code. Ridiculous, ain't it? Haha...
Admin
The main problem was that the coder was trying to generate the invalid chars dynamically and as such needed to do all of that testing for valid chars, here's the corrected version:
Admin
If it was straight append as "str" .= 0 then it'll convert it to '0', but chr(0) is going to produce a NUL.
Admin
Don't mistake a WTF in the code for a WTF in the spec.
You are right, a password with only characters and numbers is weak. But that is what the spec asked for (at least we can assume it is, as that is what the documentation claims) Maybe there is a reason for this? Perhaps this code only runs on a computer that has a keypad with only letters and numbers and a shift key? That isn't the point.
Admin
At least the code in the WTF post worked. Your code is going to generate a whole bunch of "PHP Warning: rand() expects exactly 2 parameters, 1 given" errors and its also going to generate a "PHP Notice: Undefined offset" whenever rand (which is inclusive with the limit), hits highest value.
Oh the beauty of starting arrays and strings with position 0; see now if they started at 1 errors like this wouldn't happen and you wouldn't need to constantly subtract 1 from the length to get the last char.
Why again do we start lists at 0 in so many languages?
Admin
I don't think you understand what "keyspace" means. The keyspace, FYI, indicates all the possible permutations of a key (the 'key' in this case is the password). Given the length of the 'key' is arbitrary in this code, the keyspace is also arbitrary.
A 32-bit key, obviously, has a length of 32 binary digits, making the keysize 2^32. Given that this 'key' is actually character data with 52 possible values (uc+lc+digits-disallowed) in each "digit", our key would have a length of $nlen 52ary digits or a keyspace of 52^$nlen.
Where you came up with "32-bit" is completely beyond me here.
Given that you obviously have no clue what you are talking about, perhaps you shouldn't be telling others to stay away from security programming.
Admin
A few Perl quickies, both 59 chars that use a command line issued number:
and However I did write a clean version with command line options for numeric/alpha/both(default) with full error detection (incorrect options or length < 1) and fully documented to make it idiot proof. I'd post it here but I know most people hate long code posts (at least I do).I decided on a cool approach after I read one of the above comments. Hope you enjoy it, give it a chance, its 61 characters long:
I'm happy with these, Joe PAdmin
I'll go with something, even the subject code. As obscure as it was, it at least had indentation [Okay, so maybe you don't know about code tags for posting to Web boards] and space between tokens and operators, so I found it worth reading, however clumsy it may have been.
The space-deficient, geeky crap above is a true WTF.
Admin
The real question is: who creates a random function that takes an inclusive limit? Almost all random functions are exclusive of their maximum value while inclusive of their minimum. The fact that PHP is different makes PHP the odd one out here, and suggests that PHP is confusing in this respect.
Also, you don't need to subtract one from the length for most uses of the length. The most common use of the length is to check to see if an index is in range. If you start at 0, the check is "index >= 0 && index < length". If you start at 1, the check changes to "index > 0 && index <= length". Given that starting at 0 makes memory management SO much easier, it's really simple to see why 0 is used: it makes the most sense.
It's not the first element in the list, it's the element 0 units away from the start.
Admin
Well, Unomi, even the subject snippet does provide some context in the way its coded. You can easily tell that it is aimed at three ranges of characters by reading the code, without reliance on any information external to the code. Yours relies on "Magic Numbers" and does not give any context to why they are being invoked. That can be a major problem when the code is part of a much larger system.
Provide context in your code and your variable and function names. Good programming is more than just plugging in the right numbers to get the job done. It is communication--to others who read your code and to yourself months or years hence.
Admin
Hi Checksum,
I am going to assume, despite your choice of moniker, that you are a human and not a robot that has cracked the Captcha. Bear in mind thatyour code will not be read only by a compiler, but by other humans. there is no shortage of whitespace in our environment--it's very inexpensive, and it bears great fruit in readability.
Like some other samples posted in comments, you go straight to magic numbers, without providing context. That actually makes your code less portable than the subject code, which uses ord and char as self-commenting cues to its purpose and strategy. Although it may contain some mistakes, it is actually much easier to debug.
Admin
One will be a zit. Why nine?
Seems like a perfectly memorable formulation to me.
Imagination, my boy, imagination. It is what distinguishes humans from beasts.
Admin
Not in PHP:
results run 1: 4rkKtra1 vB8hjJ1B 1gvgkpxU GFAurtST IYmwhpeg IxvmvnJy 62252I5I 510I4031 79274081
resuls run 2: cIA2rb85 pM9jIHmk RK5N0h4g ggPTphxX rMWjdUXT YVrDUwtS 86055739 61339112 72117070
Running precisely the same code.
Admin
You are right, that's what I get for not testing it first ( or least not read the documentation). the fix is:
$pwd .= $allow[rand() % $maxchr];
As for the subtraction of 1, most uses of random are with the % operator which means that it can never return grater then or equal to its divisor.
Anon explains why.
Admin
Well the code is non-deterministic. There is no way you can prove to me that this code will end. The only thing you can say is that this code will "most likely" end within a certain number of itterations. This behavior is something you should not have in a function...
The suggested aproaches about building an array of acceptable characters and then choosing the n-th chracter from that range is deterministic, since it will terminate after picking n acceptable letters.
To see how bad the performance on this can get, try to implement a shuffle algorithem that shuffels a deck of 110 cards that uses the "flawed" logic ;)
Admin
This is by far the best password generation code I've ever seen... some strings changed to protect the guilty..
$rnd = substr(str_replace(array(""",";"," ",",","
","/","=","-","_","(",")",".","?",">","<","
","'","%","$","#","@","!","*","&","^ ","+","{","}","[","]",":","\n","\r",""),"",str_shuffle(
cat /home/baddev/www/reseller/*.php`)),0,10);Admin
Apples and oranges, chief. To randomly shuffle a deck of 110 cards into the correct order on any given attempt is extremely unlikely: 1/(110!), meaning (110! - 1)/(110!) odds of having to try again, whereas in this algorithm, the chances of picking a bad character (given both alphas and numbers) is something like 23/75. That ain't great, but it approaches zero far faster than the shuffle algorithm as to make the comparison immensely unfair. For example, consider the following deterministic algorithm: Create every possibly permutation of the 110 card deck. Then, starting at the first one, go through each one until you find the permutation in the correct order. Hey, that's a terrible algorithm! Deterministic algorithms must be worthless, too! Still, I agree that a white list is the better option in this case. I just hate bad analogies.
Admin
That wasn't trav, it was you logging in as trav using one of the above passwords. Hax0r.
Admin
Unomi: Do you work for Microsoft? I find your code far more complicated than it needs to be.
Take a look at Bob's code (post 125872), except for 2 minor errors it is pure poetry.
Admin
Although I do have to agree with you that Unomi's code is a WTF, but
At least Unomi's code conformed more to the function specifications than Bob's code. A working, poorly implemented program is better than a non working program.
Problems with Bob's code
Both of them didn't remove any of "ILOQZiloqz"
To be fair:
Problems with Unomi's code
Admin
Or, ord is abbrev:ed "ordinal"?
Admin
Stupid code, the quickest and easiest code is to make a string of all valid characters. If the length is zero then doh!!, abort. Then use the random number to generate an index into that string and append characers to the password until you have generated the right number of characters.
Admin
The problem is primarily the srand() function, and secondarily the rand() function. The PHP documentation does not specify the algorithm to be used by the PHP rand() function, but does say that the libc rand() function is usually used. ANSI C does not specify the internals of the libc rand() function, either, but traditionally the libc rand() function is a particular well-known 32-bit linear congruential generator, which is seeded by calling srand(), which accepts one (1) 32-bit integer. So: the traditional random number generator starts with at most 32 bits worth of state, and therefore has only 4 billion starting points, being completely predictable from the starting point onward. Therefore, a password generator utilizing rand() can generate at most 4 billion unique passwords. A password generator which does what this one does, calling rand() and throwing away values it doesn't like, generates far fewer unique passwords, because if the initial seed is a value which will be thrown away, rand() will be called repeatedly until an acceptable value crops up, effectively making several initial values of rand() map to the same generated password.
PHP also offers a different random number generator through the mt_rand() interface, but mt_srand() also only takes a single 32-bit integer as a seed. Unless the default initialization the PHP system offers uses a different interface and jams in a larger seed, there are only 4 billion sequences that calls to mt_rand() will return. (Because mt_rand() has more than 32 bits of internal state and a fabulously long cycle time, it is possible that those 4 billion unique sequences do not generally overlap, which is not the case with the standard rand() function.)
Except for the possibility that some PHP installer might substitute a worthwhile rand() function (while stubbing out srand()), every possible password this function might generate can probably be enumerated in a matter of hours and written to a somewhat large text file. The only saving grace is that those generated passwords are roughly equiprobable (not quite true due to the collision problem mentioned above), and brute-force testing them over the web would take a long time (since the response time is going to be milliseconds to hundreds of milliseconds, not a couple of microseconds).
Admin
I think use php code AS password is the best Bye
Admin
At least it has decent comments, which is more than I can say about most code out there
captcha: noone gives a rat's ass
Admin
After reading the php source code (ah the power of open source). it seems to me that depending on what your system supports, it uses the best one (the following is based off the FreeBSD man pages).
the random() libc function has a period of >2^69 (256-bytes of state information)
the lrand48() libc function has a max period of 2^48.
and the rand() libc function has a max period of 2^31.
the mt_rand() function has a period of 2^19937-1 according to it's documentation, note I'm not a expert at this topic.
Admin
It's fundamental computer science. As fundamental as 1+1=2... as fundamental as the Peno Postulates.
There is some disagreement: http://lambda-the-ultimate.org/node/1950
But, in general the index is the array offset in memory. If an integer consumes 'm' memory elements and you have an array of integers in memory as such:
where each letter holds an arbitrary integer. Now then, to address the integer a position p you would take the position p multiply it by the consumption of 'm' and add that to the position of x in memory.
So to get the cell 'c' you would: cPointer = addressOf(x) + (2 * m); to get pointer to 'a' you would: aPointer = addressOf(x) + (0 * m);
And if your indexes started with 1 you would have to subtract 1 from the index at all times to perform this arithmetic. So by using indexes starting at zero I can see the offset of the element from the head of the array. It was a great epiphany for me to see that clearly. Indexes are not the same as first, second, third.
It also becomes important in using arrays to model 3D systems since the origin point is at 0,0,0 and not at 1,1,1. Many summation series are written to refer to i=0 to some number. Look at: http://en.wikipedia.org/wiki/Taylor_series
For non-arithmetic uses of arrays many languages provide container classes. If you plan on using elements in an array without caring too much about their precise indexes simply don't use the simple array construct, us a container class such as a list, set, or hashMap and get an iterator.
If this is too much math for you just remember it's called a computer for a reason.
Admin
you mispelled bestest
very nice code tho if reseller directory indeed exists and is full of php files, if you'd rotate them after generation as well ... would be random, wouldn't it ? :D
Admin
And that's just the first attack I could think of. Based on the left-out letters and the fact that PHP's RAND_MAX is 2^15-1 on Windows, I'm sure there are more creative attacks that can be implemented.
Admin
Admin
"Don't forget 'god', system administrators love to use 'god', it's that whole male ego thing!"
Admin
This is one of the major f**k-ups in PHP. Why not return -1 when it isn't found? This would make the function a lot better. It's like having a function like "object TestSomething(string s)" in Java or C# and the programmer has to check what type the returned object is. Not nice. But then again, PHP is filled with crap like this.
Admin
This whole nonsense reminds me of the password generator they are using at my university. It simply takes a random 40-bits number and sprintf("%X")s it. I guess they were all happy because it contains numbers AND letters, so it must be good. Too bad that it actually has a fixed short lenght, and contains only 16 possible characters. Yay security.
Admin
This is what I would use to generate a password similar to this WTF...
I think it works pretty well.
Admin
This is something I did on my second day of learning PHP:
function genPrefix ($num=5) { $letters = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', ); $code = ""; for ($i = 0; $i < $num; $i++) { $code .= $letters[mt_rand(0, count($letters))]; } return $code; }
I pray that it's gone from everywhere. I have no idea what the hell I was thinking. Sure, abusing the ASCII numerics would work, but what if I ported it to EBCDI...yeah....
Admin
That's damn awful, and you know it. Jesus. I mean, PHP is not an optimized language, truly, but COME ON! Even my retarded table lookup was faster.
..not that it wasn't retarded. ;)
Admin
Welcome to the world of DOD Classified networks.
Admin
Presumably you still can use a seed (for reproducability {is that a word}), but if you don't use a seed, the generatot will use a semi-random seed (eg timestamp + pid)
Admin
You're TRWTF. Use a trie.
Admin
In that case, aren't you suggesting that TRWTF is using passwords for the average blog or forum?
Admin
You're confused about the word "random".
Admin
Precisely. The passwords generated by this algorithm may as well be a randomised integer between PHP_INT_MIN and PHP_INT_MAX.
As an example, suppose I wanted to bruteforce a password generated by this algorithm. I could start with a seed of INT_MIN, use the same GenPswd function to generate and test corresponding passwords, iterate the seed, and repeat until I reach a correct password or a seed equal to PHP_INT_MAX.
The example doesn't just stop there. Once I find a correct password by guessing the seed, the odds are that PHP will predictably mutate the seed correctly for me. I can go forward in O(1) constant time and determine what the next password generated will likely be.