In one of the projects at my work, I got task to verify some data (in migration process from old system to new one); one of the fields was Chilean RUT (Rol Único Tributario) or Tax Identification Number.
The RUT has 8 digits plus a validation number or letter (xx.xxx.xxx-z) and algorithm for verification (as per my knowledge) is as follows:
- Remove all characters except digits and last char which can be digit or letter “K”
- Pad with zeros (“0”) string until it is exactly 9 symbols long
- Multiply, from left to right, first 8 digits with following factors: 3, 2, 7, 6, 5, 4, 3, 2 and sum those results (let’s call it total)
- Find difference: 11 – (total % 11) (let’s call it rest)
- Determine control char by:
-
5.1 If rest = 11, than control char “0” (zero)
5.2 If rest = 10, than control char “K”
5.3 Otherwise, rest is control char - If the original control char (9th char) is equal to calculated control char, RUT is valid.
C# code for this could be like this:
/// <summary> /// Routine for checking of RUT correctness /// </summary> /// <param name="rut">RUT to check</param> /// <returns>true if RUT is valid</returns> /// <remarks>Only numbers and optional "K" at the end of string are expected /// </remarks> public static bool IsRutOk(string rut) { const string RutRegex = "[0-9]+K?"; Regex RegExRut = new Regex(RutRegex, RegexOptions.Compiled | RegexOptions.IgnoreCase); int[] coefs = {3, 2, 7, 6, 5, 4, 3, 2}; // In case that rut is padded with spaces rut = rut.Trim().ToUpperInvariant(); if (!RegExRut.IsMatch(rut)) { return false; } if (rut.Length > 9) { return false; } // If shorter than 9 characters (8 + control char) ... while (rut.Length < 9) { rut = "0" + rut; } int total = 0; for (int index = 0; index < rut.Length - 1; index++) { char curr = rut.Substring(index, 1).ToCharArray()[0]; total += coefs[index]*(curr - '0'); } int rest = 11 - (total%11); if (rest == 11) rest = 0; if ((rest == 10) && rut.EndsWith("K")) { return true; } if (rut.Substring(rut.Length - 1, 1).ToCharArray()[0] == ('0' + rest)) { return true; } return false; }
You could ask me and Deki for the function or you could have written it earlier. At least one of us would not have to do it then 🙂
Good to know for next time 🙂
Hej man, otkud ti da se bavis cileanskim rutom?! :-))
Posao ne bira 🙂
Истио се и ја питам 🙂
This routine does not work and does not produce verifiable result.
If you run RUT by it and then attempt to verify it against known RUT databases – it is hit or miss like 50/50 chances.
Do not waste your time on integrating this one to your app.
This is rather bold statement, especially 50/50 part.
Do you have some examples (of not working well)?
Regards,
Dejan
HOW LONG IS A CHILEAN RUT NUMBER VALID?
Your code doesn’t do very well against this RUT generator.
http://tools.optionti.com/app/RutGenerator/
Ok, tips to fix this code and make it more reliable.
Small tip
while (rut.Length < 9) { rut = "0" + rut; } is the same thing as
rut = rut.PadLeft(9, '0');
Please always use pad left rather than writing your own.
In your code you have –
(rut.Substring(rut.Length – 1, 1).ToCharArray()[0] == ('0' + rest))
this is very odd and unreliable for comparing the last character. the below is much simpler and really cleans up a lot of error cases
if (rut.Substring(rut.Length – 1, 1) == rest.ToString())
While it doesn't seem to affect the functionality I find your handling of chars as ints in your for loop a little odd. I haven't touched it but I wonder if its better to simply treat each character as an int and do your math that way.
thanks for code, I wrote it for C++ based on yours and tested against RUT generator , is the only place on web where I found such information / constantin Romania