This should do the trick - I use this for deterministic mocking:
public static long GetDeterministicId(string m)
{
return (long) m.ToCharArray().Select((c, i) => Math.Pow(i, c%5)*Math.Max(Math.Sqrt(c), i)).Sum();
}
EDIT
if you only want number 0-9, then further mod
it by 10:
public static long GetDeterministicId(string m)
{
return (longg) m.ToCharArray().Select((c, i) => Math.Pow(i, c%5)*Math.Max(Math.Sqrt(c), i)).Sum() % 10;
}
I've ran this for 1000 most commonly used words in English (https://gist.github.com/deekayen/4148741#file-1-1000-txt) and the distribution of 0-9 is:
0 -> 156
1 -> 163
3 -> 114
7 -> 79
6 -> 72
9 -> 55
2 -> 128
8 -> 45
5 -> 89
4 -> 99
which is not perfect, but is OK.
EDIT 2
Further testing shows that replacing the first modulo by 8 (i.e. Math.Pow(i, c%8)*
) produces even better distribution:
0 -> 95
1 -> 113
2 -> 148
3 -> 91
4 -> 68
5 -> 92
6 -> 119
7 -> 79
8 -> 99
9 -> 96
EDIT 3
OK, the winner is
return (int)m.ToCharArray().Select((c, i) => Math.Pow(i+2, c % 8) * Math.Max(Math.Sqrt(c), i+2)).Sum() % 10;
and the distribution of 0 - 9 is
0 -> 90
1 -> 96
2 -> 100
3 -> 99
4 -> 97
5 -> 106
6 -> 110
7 -> 90
8 -> 103
9 -> 109
which is close enough for an even distribution!