I'm trying to develop an algorithm that generates a 16-digit validation number to interact with a given system.
This is how the algorithm should be implemented:
I have implemented it, and have it working with 2 of 3 test cases that I have found (I will post them below).
The implementations goes as:
public static String Generate(byte[] _MachineId, byte[] _SN)
{
try
{
byte[] step1 = new byte[6]
{
_SN[2],
_SN[1],
_SN[0],
_MachineId[2],
_MachineId[1],
_MachineId[0]
};
byte[] step2 = new byte[6]
{
step1[0],
step1[1],
(byte)(step1[2] ^ step1[0]),
(byte)(step1[3] ^ step1[1]),
(byte)(step1[4] ^ step1[0]),
(byte)(step1[5] ^ step1[1])
};
var crc45 = new byte[2] { step2[4], step2[5] }.GetCRCAsByteArray(0);
var crc23 = new byte[2] { step2[2], step2[3] }.GetCRCAsByteArray(0);
var crc01 = new byte[2] { step2[0], step2[1] }.GetCRCAsByteArray(0);
byte[] step3 = new byte[6]
{
crc01[0],
crc01[1],
crc23[0],
crc23[1],
crc45[0],
crc45[1]
};
string bin_to_BCD_543 = ((uint)((((0x00 << 4) | step3[5]) << 16) | ((step3[4] << 8) | step3[3]))).ToString().PadLeft(8, '0');
string bin_to_BCD_210 = ((uint)((((0x00 << 4) | step3[2]) << 16) | ((step3[1] << 8) | step3[0]))).ToString().PadLeft(8, '0');
String step4pre = bin_to_BCD_543 + bin_to_BCD_210;
Func<String, int[]> convertToIntArray =
new Func<string, int[]>(
(str) =>
{
List<int> result = new List<int>();
foreach (var c in str.ToCharArray()) result.Add(int.Parse(c.ToString()));
return result.ToArray();
}
);
int[] step4 = convertToIntArray(step4pre);
int[] step5 = step4.ToList().ToArray();
step5[8] = step4[8] | ((step4.ToList().GetRange(8, 8).Sum() % 5) << 1);
step5[0] = step4[0] | ((step4.ToList().GetRange(0, 8).Sum() % 5) << 1);
String validation = String.Join("", step5);
return validation;
}
catch (Exception exc)
{
System.Diagnostics.Trace.TraceError("Error generating Validation number. Error => " + exc.ToString());
}
return "";
}
This, are the 2 test cases that I have working:
ID = {0x21, 0x43, 0x65}, SN = {0x01, 0x00, 0x00} -> VN = "6429188185446104"
ID = {0x21, 0x43, 0x65}, SN = {0x02, 0x00, 0x00} -> VN = "2701773123879856"
I have found a 3rd case in another document, that should satisfy this:
ID = {0x01, 0x00, 0x10}, SN = {0x99, 0x00, 0x00} -> VN = "0230633823748784"
But this one does not works for me, so my questions are:
- Is the algorithm implementation OK in terms of satisfying the requirements?
- How can this implementation be improved?