Last active
August 18, 2017 19:17
-
-
Save aeppert/44ea711ce422d59551070691e9674d8f to your computer and use it in GitHub Desktop.
Verify VIN
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
| #include <vector> | |
| #include <iostream> | |
| #include <map> | |
| #include <functional> | |
| #include <numeric> | |
| using namespace std; | |
| #define VIN_LEN 17 | |
| #define VIN_CHECKDIGIT_POS 8 | |
| #define VIN_X_CHECK_DIGIT ('X' - '0') | |
| typedef std::vector<size_t> vin_vec; | |
| size_t vin_transliterate(char value) | |
| { | |
| char lv = (char)std::tolower(value); | |
| std::map<char, size_t> m = {{'a', 1}, {'b', 2}, {'c', 3}, {'d', 4}, {'e', 5}, {'f', 6}, {'g', 7}, {'h', 8}, | |
| {'j', 1}, {'k', 2}, {'l', 3}, {'m', 4}, {'n', 5}, {'p', 7}, {'r', 9}, | |
| {'s', 2}, {'t', 3}, {'u', 4}, {'v', 5}, {'w', 6}, {'x', 7}, {'y', 8}, {'z', 9}}; | |
| if( lv == 'o' || lv == 'i' || lv == 'q' ) { | |
| return -1; | |
| } | |
| if( value <= '9' ) { | |
| return value - '0'; | |
| } | |
| return m[lv]; | |
| } | |
| vin_vec vin_str_to_tl_vec(std::string vin_string) | |
| { | |
| vin_vec ret; | |
| for(string::iterator it = vin_string.begin() ; it < vin_string.end(); it++) { | |
| size_t t_ret = vin_transliterate((char)*it); | |
| if( t_ret != -1 ) { | |
| ret.push_back(t_ret); | |
| } | |
| } | |
| return ret; | |
| } | |
| bool vin_check_digit(std::string vin) | |
| { | |
| static const size_t vin_wgt_factor_array[] = {8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2}; | |
| vin_vec vin_weight_factor (vin_wgt_factor_array,vin_wgt_factor_array + sizeof(vin_wgt_factor_array) / sizeof(vin_wgt_factor_array[0])); | |
| char check_digit = vin.at(VIN_CHECKDIGIT_POS) - '0'; | |
| vin_vec tl_vec = vin_str_to_tl_vec(vin); | |
| if (tl_vec.size() != VIN_LEN) { | |
| return false; | |
| } | |
| size_t cumul = std::inner_product(tl_vec.begin(), tl_vec.end(), vin_weight_factor.begin(), 0); | |
| char t_mod = cumul % 11; | |
| return (((cumul % 11) == 10 ? VIN_X_CHECK_DIGIT : t_mod) == check_digit); | |
| } |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note: This will require compilation by a C++11 compiler (-std=c++11)