Home > Back-end >  Alphanumeric String to Unique Integer representation
Alphanumeric String to Unique Integer representation

Time:12-19

I have an input data of 4 character string (alphanumeric) or 3 character string and I need to convert these ASCII character string to unique float in 2 digits each, separated by decimal.

Ex:
Input string = 5405, output data = 54.05
Input string = 53BC, output data = 53.199 ( B ascii value is ~ 0x42 in hex and C is 0x43 )

Issue is I am seeing the same output when input strings are 560B and 5618, as both results in same output as 56.18.

Is there a way to uniquely generate a float number in these cases?

Max value of float allowed is 99.999.

CodePudding user response:

Your encoding is somewhat confusing, but here is a simple solution:

  • use 2 digits for the integral part
  • use 2 digits for fractional parts 00 to 99
  • use a combination of 1 letter and 1 letter or digit for fractional parts 100 to 999. There are 26*36 = 936 such combinations, enough to cover the 900 possibilities.
  • all values from 00.00 to 99.999 can be encoded.
  • some 4 letter and digit combinations are not used.
  • the encoding is not unique. eg: 53A0 is 53.100, the same number as 53.10 encoded as 5310.

Here is an implementation:

#include <stdib.h>

double fdecode(const char *s) {
    char a[7];
    a[0] = s[0];
    a[1] = s[1];
    a[2] = '.';
    if (s[2] >= '0' && s[2] <= '9') {
        a[3] = s[3];
        a[4] = s[4];
        a[5] = '\0';
    } else {
        // assuming uppercase letters
        int n = 100   (s[3] - 'A') * 36;
        if (s[4] >= '0' && s[4] <= '9') {
            n  = s[4] - '0';
        } else {
            n  = 10   (s[4] - 'A') % 26;
        }
        snprintf(&a[3], 4, "%d", n);
    }
    return strtod(a, NULL);
}

int fencode(char *s, double d) {
    char a[7];
    if (d >= 0 && snprintf(a, 7, ".3f", d) == 6) {
        s[0] = a[0];
        s[1] = a[1];
        if (a[5] == '0') {
            s[2] = a[3];
            s[3] = a[4];
        } else {
            int n = atoi(a   3);
            s[2] = 'A'   (n / 36);
            n %= 36;
            if (n < 10) {
                s[3] = '0'   n;
            } else {
                s[3] = 'A'   n - 10;
            }
        }
        s[4] = '\0';
        return 4;
    } else {
        s[0] = '\0';
        return -1;
    }
}

CodePudding user response:

Simple math tells us that this is not possible. The number of unique alphanumeric string of length 4 (case-insensitive) is 36^4 = 1,679,616 while the number of non-negative unique floating point numbers with at most 3 fractional digits and less than 100 is 10^5 = 100,000.

If the string were restricted to hexadecimal digits, there would only be 16^4 = 65,536 possibilities in which case a unique encoding would be possible.

Slightly off-topic: when a mapping is needed into a domain which is too small to accommodate the result of a unique mapping, a hash function is the "standard tool", but collisions must be handled.

  •  Tags:  
  • c
  • Related