Created
February 28, 2017 16:56
-
-
Save jeriley/36b29f7c46527af4532aaf092c90dd56 to your computer and use it in GitHub Desktop.
Salesforce ID checksum in C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Checksum | |
{ | |
private Dictionary<string, char> _lookup = new Dictionary<string, char>(); | |
private char[] _checksumChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345".ToCharArray(); | |
public Checksum() | |
{ | |
for (var i = 0; i < 32; i++) | |
{ | |
var bit = Convert.ToString(i, 2).PadLeft(5, '0'); | |
_lookup.Add(bit, _checksumChars[i]); | |
} | |
} | |
public bool ValidCheckSum(string salesforceId) | |
{ | |
if (salesforceId.Length != 18) | |
return false; | |
var chunks = new[] | |
{ | |
salesforceId.Substring(0, 5), | |
salesforceId.Substring(5, 5), | |
salesforceId.Substring(10, 5) | |
}; | |
var checksum = salesforceId.Substring(15, 3); | |
var calculatedChecksum = string.Empty; | |
foreach (var chunk in chunks) | |
{ | |
var reversed = chunk.Reverse().ToArray(); | |
var resultString = ""; | |
for (var i = 0; i < reversed.Count(); i++) | |
{ | |
if (char.IsUpper(reversed[i])) | |
resultString += 1; | |
else resultString += 0; | |
} | |
calculatedChecksum += _lookup[resultString]; | |
} | |
return checksum == calculatedChecksum; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[TestFixture] | |
public class SalesforceChecksumTests | |
{ | |
private Checksum _testClass = new Checksum(); | |
[Test] | |
[TestCase("a0T5000000OV7X7EAL")] | |
[TestCase("a0Q5000000IdZj4EAF")] | |
[TestCase("a0Q5000000BlbfcEAB")] | |
[TestCase("a0Q5000000J7vZwEAJ")] | |
public void valid_salesforce_Id(string id) | |
{ | |
_testClass.ValidCheckSum(id).ShouldBeTrue(); | |
} | |
[Test] | |
[TestCase("a0T5000000", Description = "too short")] | |
[TestCase("a0T5000000123512dsadf", Description = "too long")] | |
[TestCase("a0T5000000OV7X7EAX", Description = "Invalid checksum")] | |
public void InvalidChecksums(string id) | |
{ | |
_testClass.ValidCheckSum(id).ShouldBeFalse(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The performance here could probably be improved if
_lookup
was aDictionary<byte, char>
, and then you used the 5 lower bits in a byte as the key, turning flags on whenever you hit an upper case. This can be done with a bitwise OR on the key, and shift-left on the flag: