Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do reverse memcmp?

Tags:

c

memcmp

How can I do reverse memory comparison? As in, I give the ends of two sequences and I want the pointer to be decremented towards the beginning, not incremented towards the end.

like image 724
Paul Manta Avatar asked Dec 06 '11 20:12

Paul Manta


2 Answers

There's no built-in function in the C standard library to do it. Here's a simple way to roll your own:

int memrcmp(const void *s1, const void *s2, size_t n)
{
    if(n == 0)
        return 0;

    // Grab pointers to the end and walk backwards
    const unsigned char *p1 = (const unsigned char*)s1 + n - 1;
    const unsigned char *p2 = (const unsigned char*)s2 + n - 1;

    while(n > 0)
    {
        // If the current characters differ, return an appropriately signed
        // value; otherwise, keep searching backwards
        if(*p1 != *p2)
            return *p1 - *p2;
        p1--;
        p2--;
        n--;
    }

    return 0;
}

If you something high-performance, you should compare 4-byte words at a time instead of individual bytes, since memory latency will be the bottleneck; however, that solution is significantly more complex and not really worth it.

like image 167
Adam Rosenfield Avatar answered Oct 05 '22 19:10

Adam Rosenfield


Much like in a post (C memcpy in reverse) originally linked by Vlad Lazarenko, here is a solution based on that, that I haven't yet tested but should get you started.

int reverse_memcmp(const void *s1, const void *s2, size_t n)
{
    unsigned char *a, *b;
    a = s1;
    b = s2;
    size_t i = 0;

    // subtracting i from last position and comparing
    for (i = 0; i < n; i++) {
        if (a[n-1-i] != b[n-1-i]) {
            // return differences between different byte, strcmp()-style
            return (a[n-1-i] - b[n-1-i]);
        }
    }

    return 0;
}
like image 39
Dan Fego Avatar answered Oct 05 '22 19:10

Dan Fego