Viewed   70 times

I'm comparing strings with comparison operators.

I needs some short of explanations for the below two comparisons and their result.

if('ai' > 'i')
{
    echo 'Yes';
}
else
{
    echo 'No';
}

output: No

Why do these output this way?

if('ia' > 'i')
{
    echo 'Yes';
}
else
{
    echo 'No';
}

Output: Yes

Again, why?

Maybe I forgot some basics, but I really need some explanation of these comparison examples to understand this output.

 Answers

4

PHP will compare alpha strings using the greater than and less than comparison operators based upon alphabetical order.

  • In the first example, ai comes before i in alphabetical order so the test of > (greater than) is false - earlier in the order is considered 'less than' rather than 'greater than'.

  • In the second example, ia comes after i alphabetical order so the test of > (greater than) is true - later in the order being considered 'greater than'.

Wednesday, December 7, 2022
5

It looks like they're trying to prevent timing attacks.

In cryptography, a timing attack is a side channel attack in which the attacker attempts to compromise a cryptosystem by analyzing the time taken to execute cryptographic algorithms. Every logical operation in a computer takes time to execute, and the time can differ based on the input; with precise measurements of the time for each operation, an attacker can work backwards to the input.

Basically, if it takes a different amount of time to compare a correct password and an incorrect password, then you can use the timing to figure out how many characters of the password you've guessed correctly.

Consider an extremely flawed string comparison (this is basically the normal string equality function, with an obvious wait added):

function compare(a, b) {
    if(len(a) !== len(b)) { 
        return false;
    }
    for(i = 0; i < len(a); ++i) {
        if(a[i] !== b[i]) {
            return false;
        }
        wait(10); // wait 10 ms
    }
    return true;
}

Say you give a password and it (consistently) takes some amount of time for one password, and about 10 ms longer for another. What does this tell you? It means the second password has one more character correct than the first one.

This lets you do movie hacking -- where you guess a password one character at a time (which is much easier than guessing every single possible password).

In the real world, there's other factors involved, so you have to try a password many, many times to handle the randomness of the real world, but you can still try every one character password until one is obviously taking longer, then start on two character password, and so on.

This function still has a minor problem here:

if(strlen($a) !== strlen($b)) { 
    return false;
}

It lets you use timing attacks to figure out the correct length of the password, which lets you not bother guessing any shorter or longer passwords. In general, you want to hash your passwords first (which will create equal-length strings), so I'm guessing they didn't consider it to be a problem.

Friday, August 12, 2022
3

To debug a string, try this:

foreach(str_split($mystring) as $chr) {
    printf("[%02x] %s <br />",ord($chr),$chr);
}

This should, in your case, yield something like...

[48] H
[65] e
[6c] l
[6c] l
[6f] o
[0a]

Take note of that last one. 0x0a is a newline character, which is what all lines of text obtained through fgets and shell_exec end with, since that's what marks the end of the line (both functions return a "line" of output from their respective activity).

(Note: You may get [0c] [0a], or a CRLF, depending on your system.)

To fix, just use rtrim() on the string before handling it.

EDIT: Since you added in a comment that the case of 'hello ' should be allowed, then you can use something more explicit, like rtrim($mystring, "rn");

Tuesday, November 1, 2022
4

a <=> b will return -1 if a belongs before b, 0 if they're equal, or 1 if a should follow b.
b <=> a will return -1 if b belongs before a, 0 if they're equal, or 1 if b should follow a.

Since you are reversing the order, the output should be reversed, just like the - operator, for example. 3-5 is -2, and 5-3 is 2.

array.sort { |b, a| b <=> a } is equal to array.sort { |a, b| a <=> b } because the first argument is before the spaceship, and the second is after. Ruby doesn't care what the name of the variable is.

Saturday, August 6, 2022
 
akava
 
1

Javascript compares strings by character value, whether the strings look like numbers or not.

You can see this in the spec, section 11.8.5, point 4.

'a' < 'b' and 'ab' < 'ac are both true.

Wednesday, August 17, 2022
 
yoba
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :