Simple hashing algorithm TL;DR: The algorithm receives a string as input, allocate another string to be the final digest, and start working on them. For each char on the digest (a null character on a first moment), it XORs it with every character from the original string, also XORing it with a set of "random bytes" that are specified in the beginning of the code.

Here are some results:


  "000" = qpktluvsqpktluvs; "001" = bcygoiwnccxfohxn;
  
  "abc" = ayedeufryzdfftds; "cba" = cqgleoxlarrnfnvm;
  
  "aaaaa" = hingixcphingixcp; "aabaa" = aprndovlapgneovk;


Am I mathematically getting the full potential of the performance I'm using? How good would you say it is compared to other hashing algorithms? Thanks a lot for reading!
This is my first hashing algorithm. My goal is to be simple and performatic. How can I improve it?

#define HASH_LENGTH 16
char *hash(char *input){
    // Alphabet and length
    const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
    const int alphabetLen = sizeof(alphabet)/sizeof(char) - 1;

    // Randomization variables and length
    const char vars[] = {
        0xA6,
        0xC1,
        0x5E,
        0x31,
        0xF5,
        0x88,
        0xA1,
        0xE2
    };
    const int varsLen = sizeof(vars)/sizeof(char);

    // Digest (where the hash is made)
    char *digest = (char*)malloc(sizeof(char) * (HASH_LENGTH + 1));

    // Input length calculation
    int inputLen = 0;
    while(input[inputLen] != '\0') inputLen++;

    // Digest cleaning
    int i;
    for(i = 0; i &lt; HASH_LENGTH; i++){
        digest[i] = 0;  
    }

    // Hashing process
    int j;
    for(i = 0; i &lt; HASH_LENGTH; i++){
        // XORs digest[i] with vars[input[j]]
        for(j = 0; j &lt; HASH_LENGTH; j++){
            digest[i] ^= vars[input[j % inputLen] % varsLen];
        }
        // XORs digest[i] with input[i] + vars[i]
        digest[i] ^= input[i % inputLen] + vars[i % varsLen];
    }

    // Translates digest to desired alphabet
    for(i = 0; i &lt; HASH_LENGTH; i++){
        j = digest[i] &gt; 0 ? 1 : -1;
        digest[i] = alphabet[digest[i] * j % alphabetLen];
    }
    // Finalizes digest string
    *(digest + HASH_LENGTH) = '\0';

    return digest;
}


This is how the function is called:

printf("%s", hash("foo"));
I'm not particularly familiar with C, but I have a few observations that may be helpful.

I like the attention to zeroing out your digest before you start. Using uninitialised memory is the sort of bug that can go unnoticed for a while, and it's good that you've caught it. 

At the same time, I'm slightly alarmed that you're doing everything with raw loops, instead of using standard library functionality that does the same job. For example your loop to find inputLen could be replaced by a call to something like strlen and your loop to zero the array with a call to memset. As well as generally being more confident that you're using a tested and optimised routine, using library functions makes it easier to read and reason about your code.

I also quite like your use of comments. They're well placed, complementing the code and explaining some of the whys where the code explains the hows. 



As for the hashing itself, I'm sure that the output looks fairly random, but it's actually doing a lot of work for the level of hashing that it supplies. 

My top concerns:


If the input is longer than HASH_LENGTH, the latter part of the input is completely ignored.
XOR is a standard building block for this sort of low level stuff, but one of the key properties of XOR is that it undoes its own work. That is to say, because your for loop with j is only doing XOR it will confuse rather less than you'd expect for the work that goes into a nested loop. 
The space allocated to digest at the end is underused. For example, because it's restricted to that alphabet, the first three bits of every byte will be "011". That has implications for use with, say, hash maps because the hash map will allocate 87.5% of its slots to values this hash function can never fill for any possible input.