CodeSOD: Base-36 Conversion
Johannes needed to convert some data from Base-36. A helpful peer offered this solution, which... works.
int getBase36(char c) { std::map<char, int> b36; b36.insert(std::pair<char, int>( '0', 0 ); b36.insert(std::pair<char, int>( '1', 1 ); b36.insert(std::pair<char, int>( '2', 2 ); b36.insert(std::pair<char, int>( '3', 3 ); b36.insert(std::pair<char, int>( '4', 4 ); b36.insert(std::pair<char, int>( '5', 5 ); b36.insert(std::pair<char, int>( '6', 6 ); b36.insert(std::pair<char, int>( '7', 7 ); b36.insert(std::pair<char, int>( '8', 8 ); b36.insert(std::pair<char, int>( '9', 9 ); b36.insert(std::pair<char, int>( 'a', 10 ); b36.insert(std::pair<char, int>( 'b', 11 ); b36.insert(std::pair<char, int>( 'c', 12 ); b36.insert(std::pair<char, int>( 'd', 13 ); b36.insert(std::pair<char, int>( 'e', 14 ); b36.insert(std::pair<char, int>( 'f', 15 ); b36.insert(std::pair<char, int>( 'g', 16 ); b36.insert(std::pair<char, int>( 'h', 17 ); b36.insert(std::pair<char, int>( 'i', 18 ); b36.insert(std::pair<char, int>( 'j', 19 ); b36.insert(std::pair<char, int>( 'k', 20 ); b36.insert(std::pair<char, int>( 'l', 21 ); b36.insert(std::pair<char, int>( 'm', 22 ); b36.insert(std::pair<char, int>( 'n', 23 ); b36.insert(std::pair<char, int>( 'o', 24 ); b36.insert(std::pair<char, int>( 'p', 25 ); b36.insert(std::pair<char, int>( 'q', 26 ); b36.insert(std::pair<char, int>( 'r', 27 ); b36.insert(std::pair<char, int>( 's', 28 ); b36.insert(std::pair<char, int>( 't', 29 ); b36.insert(std::pair<char, int>( 'u', 30 ); b36.insert(std::pair<char, int>( 'v', 31 ); b36.insert(std::pair<char, int>( 'w', 32 ); b36.insert(std::pair<char, int>( 'x', 33 ); b36.insert(std::pair<char, int>( 'y', 34 ); b36.insert(std::pair<char, int>( 'z', 35 ); return b36.find(c)->second;}
Using a map does save doing a linear search for each character in our input, which is potentially a meaningful optimization, but since we construct the map for each character, we've immediately lost that optimization. Worse, we use the map's find method, which returns an iterator, because the purpose of that method is to search a map for matching keys (allowing you to pass search terms of a different type than the keys themselves, so long as you have overloaded some comparison operators). In this case, it likely wouldn't do a search, and still be O(1), but it's the wrong method to call when at or [] would be more correct.
Speaking of the wrong method- if the character isn't in this map (because you got bad input), this helpfully fails silently and just returns 0 because that's an uninitialized pair. Perhaps that's an intentional choice, but doing it implicitly like this is certainly going to cause errors.
Oh, and the syntax is wrong, as every line is missing a parenthesis. But Johannes' helper was adamant that this was the best possible solution. It was the one that Johannes should use. Johannes was wrong for discarding it so quickly.
Johannes, however, after a few more seconds of searching, found strtol, a standard function that converts a string in any base up to base-36 to a long.
[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!