Live data from Hacker News

PHP: md5('240610708') == md5('QNKCDZO')

3v4l.org

171–180 of 185 posts

Re: PHP: md5('240610708') == md5('QNKCDZO')

#173
post #93

Earlier quoted context omitted.

There are a couple of things we have learnt in our collective 50+ years of software engineering: 1. Code is not English: Nice try COBOL, and someone had to try, but a failed experiment. Bizarre holdouts: SQL 2. People are not idiots, and will not collapse into a gibbering heap if their programming language insists that 0 and "0" are different things and must be managed accordingly. Bizarre holdouts: PHP, Javascript.…

Absolutely, to be fair to JS, Eich admitted it was an horrible mistake, and tools like JSlint enforce the use of === . I didn't see any meaculpa from the PHP team yet.Would like to read about it.

They're sorry you're such a terrible coder, worse than Rasmus Lerdorf himself:

"For all the folks getting excited about my quotes. Here is another - Yes, I am a terrible coder, but I am probably still better than you :)" - http://en.wikiquote.org/wiki/Rasmus_Lerdorf

Re: PHP: md5('240610708') == md5('QNKCDZO')

#174
post #160

Earlier quoted context omitted.

12 is not 0.

Yes and no. JavaScript gives you the good ol' "NaN" which is a number (despite not being a number). PHP doesn't have that concept in it.

Sort of. 'NaN' is one of the IEEE 754 floating point constants, along with 'Inf' for infinity. They are numeric types, in that they can be returned via operations on numbers, such as dividing zero by zero or adding '-Inf' to 'Inf'. See https://en.wikipedia.org/wiki/NaN

I always understood that the 'isNaN()' function was required to check if a numeric variable is equal to 'NaN' directly, since normal equality cannot be used as there are multiple valid bitwise representations of 'NaN' in the standard - it is a float with an exponent of all ones and a non-zero fraction. However, 'isNaN()' now seems to have been co-opted into being used to check if a string is not a number, i.e. does not represent a numeric value, and in fact I believe this is now the documented description of the function in ECMAScript?

Re: PHP: md5('240610708') == md5('QNKCDZO')

#175
slightly off topic:

  $a = "DjBlYVWap4fQC8b3C73+NATPA2We"."c"."E+FNMAP+2WcTIdAzJQv6y2hFaP0F"."V"."y7hgdJc4ZlbX0fNKQgWdePWo3R7w";
  $b = "DjBlYVWap4fQC8b3C73+NATPA2We"."d"."E+FNMAP+2WcTIdAzJQv6y2hFaP0F"."d"."y7hgdJc4ZlbX0fNKQgWdePWo3R7w";
  var_dump($a === $b); // false
  var_dump(md5(base64_decode($a)) === md5(base64_decode($b))); // true
:-P

Re: PHP: md5('240610708') == md5('QNKCDZO')

#176

Earlier quoted context omitted.

Nah, the problem is PHP. See: http://blog.codinghorror.com/falling-into-the-pit-of-success... > When you write code in [PHP], you're always circling the pit of despair, just one misstep away from plunging to your doom.

No, the problem is using a shitty function like MD5 for any practical purpose.

The hash function is completely irrelevant to this bug - whether you use a hash that returns 0 for every input, or invent a hash function that returns a perfectly unique and unpredictable hash for all inputs, PHP will still shoot you in the foot.

Re: PHP: md5('240610708') == md5('QNKCDZO')

#177
post #98

Earlier quoted context omitted.

To be fair, this kind of thing (maybe not exactly this, but type-coercion bugs) can happen in JavaScript, which is all the rage now for "important" stuff.

Yeah but javascript has 'use strict' whereas PHP decided that the easter egg "looks like you're using the wrong language!" was more important than actually allowing a 'use strict' to force === instead of ==.

I don't think strict mode affects == vs. === Best bet is to use a linter to catch that.

Re: PHP: md5('240610708') == md5('QNKCDZO')

#178
Nothing magic here. Be careful with the == comparison operator and its type juggling. If you want to match things precisely, use the === operator. Loose comparisons can have dangerous side-effects!

The MD5 examples are really just cloaked comparisons like this one, later in the list:

var_dump('0010e2' == '1e3');

((10 x 10^2) == (1 * 10^3))

http://php.net/manual/en/language.operators.comparison.php

http://php.net/manual/en/types.comparisons.php

Re: PHP: md5('240610708') == md5('QNKCDZO')

#179
post #123
post #116

Earlier quoted context omitted.

This truly just bummed me out :(

Don't let it - he understands exactly how the types are being converted in order to make it appear that true == false. This sort of thing happens in type conversion languages. You can either use === to stop conversion or you can understand how conversion works. I'm not sure how the order of conversions is decided by PHP, but here's a brief explanation: Compare "foo" to true. Convert the string "foo" to a boolean valu…

> This sort of thing happens in type conversion languages. You can either use === to stop conversion or you can understand how conversion works.

You must admit that this is a lot of behavior to keep in mind.

Eg, there is no pattern like "try converting the value on the right to the type of the value on the left".

> Compare "foo" to 0. Convert the string "foo" to a numeric value.

I would expect this to convert 0 to "0" and fail. I suppose it's done this way because there's no way to represent a hexadecimal number except as a string.

> The moral of the story, == is not "exactly equal" it is "relatively equal."

The moral of the story for me would be "never use ==", if I were using PHP. I don't want to think about so many rules when trying to do a simple comparison.

FWIW, Ruby allows type conversion, but it generally must be explicit: `5 == "5"` is false; you must either do `5.to_s` or `"5".to_i` to compare, therefore nothing unexpected can happen. `if some_var` does "convert" to a boolean, but the rule is "nil and false are falsey, everything else is truthy", so again, not much to remember.

"Hard to mess up" is better than "easy to mess up", even if it's possible to avoid the mistake.

Re: PHP: md5('240610708') == md5('QNKCDZO')

#180
post #129
post #123

Earlier quoted context omitted.

Don't let it - he understands exactly how the types are being converted in order to make it appear that true == false. This sort of thing happens in type conversion languages. You can either use === to stop conversion or you can understand how conversion works. I'm not sure how the order of conversions is decided by PHP, but here's a brief explanation: Compare "foo" to true. Convert the string "foo" to a boolean valu…

The problem with designing a language that does these sorts of implicit type conversions is that the "equality" operator violates the fundamental properties of equality. Since grade school mathematics we are all taught that equality is symmetric and transitive, and PHP's == operator is neither.

AFAIK == is always symmetric.
Post reply on HN