Task: IBAN

C: #include <alloca.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define V(cc, exp) if (!strncmp(iban, cc, 2)) return len == exp


int valid_cc(const char *iban, int len)
{
    V("AL", 28); V("AD", 24); V("AT", 20); V("AZ", 28); V("BE", 16); V("BH", 22); V("BA", 20); V("BR", 29);
    V("BG", 22); V("CR", 21); V("HR", 21); V("CY", 28); V("CZ", 24); V("DK", 18); V("DO", 28); V("EE", 20);
    V("FO", 18); V("FI", 18); V("FR", 27); V("GE", 22); V("DE", 22); V("GI", 23); V("GR", 27); V("GL", 18);
    V("GT", 28); V("HU", 28); V("IS", 26); V("IE", 22); V("IL", 23); V("IT", 27); V("KZ", 20); V("KW", 30);
    V("LV", 21); V("LB", 28); V("LI", 21); V("LT", 20); V("LU", 20); V("MK", 19); V("MT", 31); V("MR", 27);
    V("MU", 30); V("MC", 27); V("MD", 24); V("ME", 22); V("NL", 18); V("NO", 15); V("PK", 24); V("PS", 29);
    V("PL", 28); V("PT", 25); V("RO", 24); V("SM", 27); V("SA", 24); V("RS", 22); V("SK", 24); V("SI", 19);
    V("ES", 24); V("SE", 24); V("CH", 21); V("TN", 24); V("TR", 26); V("AE", 23); V("GB", 22); V("VG", 24);

    return 0;
}


int strip(char *s)
{
    int i = -1, m = 0;

    while(s[++i]) {
        s[i - m] = s[i];
        m += s[i] <= 32;
    }

    s[i - m] = 0;
    return i - m;
}


int mod97(const char *s, int len)
{
    int i, j, parts = len / 7;
    char rem[10] = "00";

    for (i = 1; i <= parts + (len % 7 != 0); ++i) {
        strncpy(rem + 2, s + (i - 1) * 7, 7);
        j = atoi(rem) % 97;
        rem[0] = j / 10 + '0';
        rem[1] = j % 10 + '0';
    }

    return atoi(rem) % 97;
}

int valid_iban(char *iban)
{
    int i, j, l = 0, sz = strip(iban);
    char *rot, *trans;

    
    for (i = 0; i < sz; ++i) {
        if (!isdigit(iban[i]) && !isupper(iban[i]))
            return 0;
        l += !!isupper(iban[i]);
    }

    if (!valid_cc(iban, sz))
        return 0;

    
    rot = alloca(sz);
    strcpy(rot, iban + 4);
    strncpy(rot + sz - 4, iban, 4);

    
    trans = alloca(sz + l + 1);
    trans[sz + l] = 0;

    
    for (i = j = 0; i < sz; ++i, ++j) {
        if (isdigit(rot[i]))
            trans[j] = rot[i];
        else {
            trans[j]   = (rot[i] - 55) / 10 + '0';
            trans[++j] = (rot[i] - 55) % 10 + '0';
        }
    }

    return mod97(trans, sz + l) == 1;
}

int main(int _, char **argv)
{
    while (--_, *++argv)
        printf("%s is %svalid.\n", *argv, valid_iban(*argv) ? "" : "in");

    return 0;
}



C#:     public class IbanValidator : IValidateTypes
    {
        public ValidationResult Validate(string value)
        {
            
            if (string.IsNullOrEmpty(value))
                return ValidationResult.ValueMissing;

            if (value.Length < 2)
                return ValidationResult.ValueTooSmall;

            var countryCode = value.Substring(0, 2).ToUpper();

            int lengthForCountryCode;

            var countryCodeKnown = Lengths.TryGetValue(countryCode, out lengthForCountryCode);
            if (!countryCodeKnown)
            {
                return ValidationResult.CountryCodeNotKnown;
            }

            
            if (value.Length < lengthForCountryCode)
                return ValidationResult.ValueTooSmall;

            if (value.Length > lengthForCountryCode)
                return ValidationResult.ValueTooBig;

            value = value.ToUpper();
            var newIban = value.Substring(4) + value.Substring(0, 4);

            newIban = Regex.Replace(newIban, @"\D", match => (match.Value[0] - 55).ToString());

            var remainder = BigInteger.Parse(newIban) % 97;

            if (remainder != 1)
                return ValidationResult.ValueFailsModule97Check;

            return ValidationResult.IsValid;
        }

        public enum ValidationResult
        {
            IsValid,
            ValueMissing,
            ValueTooSmall,
            ValueTooBig,
            ValueFailsModule97Check,
            CountryCodeNotKnown
        }

        private static readonly IDictionary<string, int> Lengths = new Dictionary<string, int>
        {
            {"AL", 28},
            {"AD", 24},
            {"AT", 20},
            {"AZ", 28},
            {"BE", 16},
            {"BH", 22},
            {"BA", 20},
            {"BR", 29},
            {"BG", 22},
            {"CR", 21},
            {"HR", 21},
            {"CY", 28},
            {"CZ", 24},
            {"DK", 18},
            {"DO", 28},
            {"EE", 20},
            {"FO", 18},
            {"FI", 18},
            {"FR", 27},
            {"GE", 22},
            {"DE", 22},
            {"GI", 23},
            {"GR", 27},
            {"GL", 18},
            {"GT", 28},
            {"HU", 28},
            {"IS", 26},
            {"IE", 22},
            {"IL", 23},
            {"IT", 27},
            {"KZ", 20},
            {"KW", 30},
            {"LV", 21},
            {"LB", 28},
            {"LI", 21},
            {"LT", 20},
            {"LU", 20},
            {"MK", 19},
            {"MT", 31},
            {"MR", 27},
            {"MU", 30},
            {"MC", 27},
            {"MD", 24},
            {"ME", 22},
            {"NL", 18},
            {"NO", 15},
            {"PK", 24},
            {"PS", 29},
            {"PL", 28},
            {"PT", 25},
            {"RO", 24},
            {"SM", 27},
            {"SA", 24},
            {"RS", 22},
            {"SK", 24},
            {"SI", 19},
            {"ES", 24},
            {"SE", 24},
            {"CH", 21},
            {"TN", 24},
            {"TR", 26},
            {"AE", 23},
            {"GB", 22},
            {"VG", 24}
        };
    }