Caesar cipher : how to calculate with shifting value > 10 ( or larger )? - c++

As i know , the " formula " of Caesar Shifting is (x + k ) % 26 , where k is the shifting value and decryption just replace " + " to " - ".
but my code does not work when k > 10 (after i tested k = 10 , i find that the "shift" of the first few characters is wrong, so I estimate that k > 10 will be wrong (the number of incorrect characters increase) as well. ). I first change the characters to ASCII and then do the calculation. Finally change it back to characters.
Here are my code.
#include <iostream>
#include <string>
using namespace std;
int main() {
string target;
char s;
int k, i, num, length, j;
cin >> s >> k;
getline(cin, target);
for (j = 0; j <= (int)target.length(); j++) {
if ((target[j]) = ' ') {
target.erase(j, 1);
}
}
length = (int)target.length();
if (s == 'e') {
for (num = 0; num <= length; num++) {
if (isupper(target[num]))
target[num] = tolower(char(int(target[num] + k - 65) % 26 + 65));
else if (islower(target[num]))
target[num] = toupper(char(int(target[num] + k - 97) % 26 + 97));
}
}
else if (s == 'd') {
for (num = 0; num <= length; num++) {
if (isupper(target[num]))
target[num] = tolower(char(int(target[num] - k - 65) % 26 + 65));
else if (islower(target[num]))
target[num] = toupper(char(int(target[num] - k - 97) % 26 + 97));
}
}
cout << target;
return 0;
}
Let me put down the case which i failed to run.
input:
d 10 n 3 V 3 D 3 N _ M Y N 3 _ S C _ N 3 L E ( input d / e first, then shifting value, finally the sequence of string require to " change ", the space is required to delete. )
the expected output:
D3l3t3d_cod3_is_d3bu
my output:
D3l3:3d_cod3_i9_d3b;
Thanks!

Your issue is that when decoding you end up with negative numbers. With k == 13 the expression 'T' - k - 65 gives -7. -7 % 26 is still -7. -7+65 is 58 which isn't a letter.
You can avoid negative numbers by simply setting k to 26 - k when decoding.
Your code then simplifies to:
if (s == 'd') {
k = 26 - k;
}
for (num = 0; num <= length; num++) {
if (isupper(target[num]))
target[num] = tolower(char(int(target[num] + k - 'A') % 26 + 'A'));
else if (islower(target[num]))
target[num] = toupper(char(int(target[num] + k - 'a') % 26 + 'a'));
}
Note I've replaced your integer constants with their equivalent characters which makes the code much easier to understand.
Note you also have a bug in your first loop (target[j]) = ' ' should be (target[j]) == ' '.
Using all c++ has to offer you can reduce your code to:
#include <iostream>
#include <string>
#include <algorithm>
int main() {
std::string target = "mXLM";
char s = 'e';
int k = 7;
target.erase(std::remove(target.begin(), target.end(), ' '), target.end());
if (s == 'd') {
k = 26 - k;
}
std::string result;
std::transform(target.begin(), target.end(), std::back_inserter(result), [k](char in) {
if (isalpha(in)) {
char inputOffset = isupper(in) ? 'A' : 'a';
char outputOffset = isupper(in) ? 'a' : 'A';
return char(int(in + k - inputOffset) % 26 + outputOffset);
}
return in;
});
std::cout << result;
return 0;
}

Related

Implementation Working in Python But Not in C++

So I made a program that takes in three strings, A, B, and C and determines whether or not C is a merge of A and B. A merge is defined as combination of the letters in A and B such that the ordering of the letters of A and B in relation to one another are preserved. So if A = "ab", B = "ba", and C = "abab", C is a valid merge of A and B since the first and last letters of C can be thought of as "from A" and the middle two from B. This combination of letters preserves their order in A and B and so C is a valid merge.
My program also capitalizes the letters in C that are "from A" meaning it outputs "AbaB".
I'm more comfortable with Python so I wrote out my implementation there first and then translated it to C++. But the really weird thing is that it works perfectly in Python but not in C++. I checked line by line and everything matches up perfectly but it's still giving the wrong output.
So for an example, for the input A == "ab", B = "ba", and C = "abab", my Python implementation correctly outputs "AbaB". But, my C++ implementation outputs "ABba".
The problem only seems to be with this part of the output. The C++ program seems to be able to correctly identify whether or not C is a valid merge of A and B.
Here's my Python program:
def findPath(array, A, B):
output = ""
M = len(A)
N = len(B)
i = M
j = N
while(j > 0):
print(i,j)
if(array[i][j-1]):
output = B[j-1] + output
j -= 1
else:
output = A[i-1].upper() + output
i -= 1
while(i > 0):
output = A[i-1].upper() + output
i -= 1
return output
def isInterleaved(A,B,C):
M = len(A)
N = len(B)
output = ""
array = [[False] * (N + 1) for i in range(M + 1)]
if(M +N != len(C)):
return False
for i in range(M+1):
for j in range(N+1):
if (i== 0 and j == 0):
array[i][j] = True
elif (i == 0):
if (B[j-1] == C[j-1]):
array[i][j] = array[i][j-1]
elif (j == 0):
if (A[i-1] == C[i-1]):
array[i][j] = array[i-1][j]
elif (A[i - 1] == C[i + j - 1] and B[j - 1] != C[i + j - 1]):
array[i][j] = array[i-1][j]
elif (A[i - 1] != C[i + j - 1] and B[j - 1] == C[i + j - 1]):
array[i][j] = array[i][j-1]
elif (A[i - 1] == C[i + j - 1] and B[j - 1] == C[i + j - 1]):
array[i][j] = (array[i - 1][j] or array[i][j - 1])
print(findPath(array, A,B))
return array[M][N]
print(isInterleaved("ab", "ba",
"abab"))
And here's my C++ program:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
bool graph[1001][1001];
bool isInterleaved(string A, string B, string C)
{
int M = A.size();
int N = B.size();
if(M + N != C.size())
{
return false;
}
for (int i = 0; i < M + 1; i++)
{
for(int j = 0; j < N + 1; j++)
{
if (i == 0 and j == 0) { graph[i][j] = true; }
else if(i == 0)
{
if (B[j-1] == C[j-1])
{
graph[i][j] = graph[i][j-1];
}
}
else if(j == 0)
{
if (A[i-1] == C[i-1]) { graph[i][j] = graph[i-1][j];}
}
else if (A[i - 1] == C[i + j - 1] and B[j - 1] != C[i + j - 1])
{
graph[i][j] = graph[i-1][j];
}
else if (A[i - 1] != C[i + j - 1] and B[j - 1] == C[i + j - 1])
{
graph[i][j] = graph[i][j-1];
}
else if (A[i - 1] == C[i + j - 1] and B[j - 1] == C[i + j - 1])
{
graph[i][j] = (graph[i - 1][j] or graph[i][j - 1]);
}
}
}
return graph[M][N];
}
string findPath(string A, string B)
{
string output = "";
int M = A.size();
int N = B.size();
int i = M;
int j = N;
for(int k = 0; k < M; k++)
{
A[k] = toupper(A[k]);
}
while(j > 0)
{
if(graph[i][j-1])
{
output = B[j - 1] + output;
j -= 1;
}
else
{
output = A[i-1]+ output;
i -= 1;
}
}
cout << output << endl;
while(i > 0)
{
output = A[i-1] + output;
i -= 1;
}
return output;
}
int main()
{
string in;
string out;
cout << "Enter the name of input file: ";
cin >> in;
cout << "Enter the name of output file: ";
cin >> out;
ifstream myfile;
myfile.open(in);
ofstream outfile;
outfile.open(out);
string line;
vector<string> arguments;
int count = 0;
while(getline(myfile, line))
{
arguments.push_back(line);
count ++;
if(count == 3)
{
count = 0;
if(isInterleaved(arguments[0], arguments[1], arguments[2]))
{
outfile << findPath(arguments[0], arguments[1]) << "\n";
}
else
{
outfile << "*** NOT A MERGE ***" << "\n";
}
arguments.clear();
}
}
myfile.close();
outfile.close();
return 0;
}
For the C implementation, it takes in a list of test cases so that every block of three lines gives the parameters for a different test case. The first line gives the string A, the second, the string B, and the third, is C. It outputs the results into a text file giving the capitalized-A version of C when it's a valid merge and the string "*** NOT A MERGE ***" when it's not.
Any help with this would be greatly appreciated. I'm pretty sure it has to be something small like a method that's not giving me what I expect it to.
This is not really an answer, but sometimes when things don’t work it’s better to start over from an easily testable MWE. I’d suggest keeping it trivial, without file I/O clutter, focused only on the merger detection and without an arbitrary hard limit of 1000:
#include <iostream>
#include <set>
#include <string_view>
#include <tuple>
int main(int argc, const char *const *argv) {
if (argc != 4) return 3;
const std::string_view a{argv[1]}, b{argv[2]}, c{argv[3]};
const auto report{[a, b, c](bool result) {
std::cout << '\'' << c << "' is " << (result ? "" : "NOT ")
<< "a merger of '" << a << "' and '" << b << "'\n";
}};
std::set<std::tuple<size_t, size_t>> state{{0, 0}};
do {
const auto s{state.begin()};
const auto [pc, pa] = *s;
const size_t pb = pc - pa;
state.erase(s);
if (pc < c.size()) {
if (pa < a.size() && c[pc] == a[pa])
state.emplace_hint(state.end(), pc + 1, pa + 1);
if (pb < b.size() && c[pc] == b[pb])
state.emplace_hint(state.end(), pc + 1, pa);
} else if (pa == a.size() && pb == b.size()) {
report(true);
return 0;
}
} while (!state.empty());
report(false);
return 1;
}
What it does is (indeed) trivial: It records combinations of (position in merger candidate C, position in merger input A [explicit], position in merger input B [implicit]) achieved thus far. Obviously, (0, 0, 0) is a trivially satisfied starting point. Then it keeps trying to advance each already achieved position by one character. Ultimately it either reaches the ends of all of A, B and C at once, at which point C is confirmed to be a merger of A and B, or it exhausts all achieved positions recorded for future consideration, which means that one cannot merge A and B into C in any way.
(Presumably, you need to add an extra piece of data into the state if you want to also report a “merger recipe” together with a positive answer. It could also use an early check whether the string lengths add up.)
Now we can test that a bit (assuming that the binary is called merger):
#!/bin/bash
abc012=(abc012 ab0c12 ab01c2 ab012c a0bc12 a0b1c2 a0b12c a01bc2 a01b2c a012bc
0abc12 0ab1c2 0ab12c 0a1bc2 0a1b2c 0a12bc 01abc2 01ab2c 01a2bc 012abc)
acb012=(acb012 ac0b12 ac01b2 ac012b a0cb12 a0c1b2 a0c12b a01cb2 a01c2b a012cb
0acb12 0ac1b2 0ac12b 0a1cb2 0a1c2b 0a12cb 01acb2 01ac2b 01a2cb 012acb)
for m in "${abc012[#]}"; do
./merger abc 012 "$m" # …is a merger…
done
for m in "${acb012[#]}"; do
./merger abc 012 "$m" # …is NOT a merger…
done

Coursera DSA Algorithmic toolbox week 4 2nd question- Partitioning Souvenirs

Problem Statement-
You and two of your friends have just returned back home after visiting various countries. Now you would
like to evenly split all the souvenirs that all three of you bought.
Problem Description
Input Format- The first line contains an integer ... The second line contains integers v1, v2, . . . ,vn separated by spaces.
Constraints- 1 . .. . 20, 1 . .... . 30 for all ...
Output Format- Output 1, if it possible to partition 𝑣1, 𝑣2, . . . , 𝑣𝑛 into three subsets with equal sums, and
0 otherwise.
What's Wrong with this solution? I am getting wrong answer when I submit(#12/75) I am solving it using Knapsack without repetition taking SUm/3 as my Weight. I back track my solution to replace them with 0. Test cases run correctly on my PC.
Although I did it using OR logic, taking a boolean array but IDK whats wrong with this one??
Example- 11
17 59 34 57 17 23 67 1 18 2 59
(67 34 17)are replaced with 0s. So that they dont interfare in the next sum of elements (18 1 23 17 59). Coz both of them equal to 118(sum/3) Print 1.
#include <iostream>
#include <vector>
using namespace std;
int partition3(vector<int> &w, int W)
{
int N = w.size();
//using DP to find out the sum/3 that acts as the Weight for a Knapsack problem
vector<vector<int>> arr(N + 1, vector<int>(W + 1));
for (int k = 0; k <= 1; k++)
{
//This loop runs twice coz if 2x I get sum/3 then that ensures that left elements will make up sum/3 too
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < W + 1; j++)
{
if (i == 0 || j == 0)
arr[i][j] = 0;
else if (w[i - 1] <= j)
{
arr[i][j] = ((arr[i - 1][j] > (arr[i - 1][j - w[i - 1]] + w[i - 1])) ? arr[i - 1][j] : (arr[i - 1][j - w[i - 1]] + w[i - 1]));
}
else
{
arr[i][j] = arr[i - 1][j];
}
}
}
if (arr[N][W] != W)
return 0;
else
{
//backtrack the elements that make the sum/3 and = them to 0 so that they don't contribute to the next //elements that make sum/3
int res = arr[N][W];
int wt = W;
for (int i = N; i > 0 && res > 0; i--)
{
if (res == arr[i - 1][wt])
continue;
else
{
std::cout << w[i - 1] << " ";
res = res - w[i - 1];
wt = wt - w[i - 1];
w[i - 1] = 0;
}
}
}
}
if (arr[N][W] == W)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n;
std::cin >> n;
vector<int> A(n);
int sum = 0;
for (size_t i = 0; i < A.size(); ++i)
{
int k;
std::cin >> k;
A[i] = k;
sum += k;
}
if (sum % 3 == 0)
std::cout << partition3(A, sum / 3) << '\n';
else
std::cout << 0;
}
Sum/3 can be achieved by multiple ways!!!! So backtracking might remove a subset that has an element that should have been a part of some other subset
8 1 6 is 15 as well as 8 2 5 makes 15 so better is u check this
if(partition3(A, sum / 3) == sum / 3 && partition3(A, 2 * (sum / 3)) == 2 * sum / 3 && sum == partition3(A, sum))

How to cyclically increment and decrement 26 latin characters in a loop

I want to increment or decrement characters, but have them cycle back to a when going beyond z and to z when going before a.
For example incrementing 'w' by 2 gives 'y' and decrementing 'w' by 2 gives 'u'.
Another example decrementing 'w' by 28 gives 'u' and decrementing 'a' by 256 gives 'e'.
I've figure out how to increment: char(int(A[i]+B-97)%26 +97) where B is the shift amount and A[i] is current character.
Don't overcomplicate. Use modulo to keep the increment or decrement amount in a range of 26 characters, then simply do a range check:
char cyclicIncrementDecrement(char ch, int amount)
{
int newValue = int(ch) + (amount % 26);
if (newValue < 'a') newValue += 26;
if (newValue > 'z') newValue -= 26;
return char(newValue);
}
This method of course assumes ch already is in range of 'a' to 'z'. If not, you need to handle that (put it in range or throw an exception or whatever is appropriate for your application).
Running this:
int main()
{
std::cout << cyclicIncrementDecrement('w', -2) << std::endl;
std::cout << cyclicIncrementDecrement('w', 2) << std::endl;
std::cout << cyclicIncrementDecrement('w', -28) << std::endl;
std::cout << cyclicIncrementDecrement('a', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -256) << std::endl;
std::cout << cyclicIncrementDecrement('z', -51) << std::endl;
std::cout << cyclicIncrementDecrement('z', -52) << std::endl;
}
gives:
u
y
u
e
d
a
z
Using modular arithmetic, calculate your answer as modulo 26 and then add 'a' (ASCII 97) to your result.
char cyclic_increment(char ch, int n) {
int tmp = ((ch - 97) + n) % 26;
if (tmp < 0 )
tmp += 26;
return (char)(tmp + 97);
}
Alternatively, you could write the above (without an if) as:
char cyclic_increment(char ch, int n) {
return (((ch - 'a') + n) % 26 + 26) % 26 + 'a';
}
This handles both positive and negative offsets:
unsigned char az_cyclic(int in_ch)
{
constexpr int mod = 26; // There are 26 letters in the English alphabet
int offset = (in_ch - 'a') % mod; // (ASCII To zero-based offset) Mod_26 remainder
if (offset < 0) // If negative offset,
offset += mod; // normalize to positive. For example: -1 to 25
return 'a' + offset; // Normalize to ASCII
}
Use-cases:
int main()
{
unsigned char out_ch = '\0';
out_ch = az_cyclic('a' - 1); // 'z'
out_ch = az_cyclic('a' - 1 - 26); // 'z'
out_ch = az_cyclic('a' - 2); // 'y'
out_ch = az_cyclic('a' + 4); // 'e'
out_ch = az_cyclic('a' + 4 + 26); // 'e'
out_ch = az_cyclic('a' + 2); // 'c'
return 0;
}

Renaming filenames in two directories IF certain characters between them match - vector subscript out of range

My first job as an intern was to write a program to compare certain characters in the filenames of two different directories, and if they match, rename them. I wrote a custom code to match the characters. The initial few files get renamed in both directories, but it breaks after a point, giving a vector subscript out of range error.
I have an idea of how to fix such a vector range error from all the other posts, but nothing seemed to work. Any input would be appreciated!
PS: I am not a coder and this is my third official program. I understand the code is a bit messy.
Here is the code:
#include<dirent.h>
#include<vector>
#include<sstream>
int main()
{
cout << "Comparer - Renamer v.0.1.beta\n\n";
string dr1, dr2;
int x, y;
DIR *d1;
struct dirent *dir1;
vector<string> a;
a.reserve(25000);
int i = 0;
cout << "Enter the first directory (format : log_2017...) : ";
cin >> dr1;
d1 = opendir(dr1.c_str());
if (d1){
while ((dir1 = readdir(d1)) != NULL){
i++;
a.push_back(dir1->d_name);
}
closedir(d1);
}
x = a.size();
cout << "\nEnter the second directory (format : 2017.12...) : ";
cin >> dr2;
DIR *d2;
struct dirent *dir2;
vector<string> b;
b.reserve(25000);
int j = 0;
d2 = opendir(dr2.c_str());
if (d2){
while ((dir2 = readdir(d2)) != NULL){
j++;
b.push_back(dir2->d_name);
}
closedir(d2);
}
y = b.size();
ostringstream osa, nsa, osb, nsb;
string oldname_a, newname_a, oldname_b, newname_b;
int u, v, w;
for (int l = 2; l < x; l++){
for (int k = l; k < y; k++){
int c = a[l][20] * 10 + a[l][21];
int d = b[k][14] * 10 + b[k][15];
int e = a[l][17] * 10 + a[l][18];
int f = b[k][11] * 10 + b[k][12];
if (a[l][4] == b[k][0] && a[l][5] == b[k][1] && a[l][6] == b[k][2] && a[l][7] == b[k][3] && a[l][9] == b[k][5] && a[l][10] == b[k][6] && a[l][12] == b[k][8] && a[l][13] == b[k][9]){
u = 0;
}
else{
u = 1;
}
if ((e - f) == 0 && abs(c - d) < 12){
v = 0;
}
else{
v = 1;
}
if ((e - f) == 1 && ((c == 58) || (c == 59) || (c == 0) || (c == 1) || (c == 2))){
w = 0;
}
else{
w = 1;
}
if (u == 0 && (v == 0 || w == 0)){
osa.str(string());
osa << dr1 << "\\" << a[l];
nsa.str(string());
nsa << dr1 << "\\" << l - 1 << ". " << a[l];
oldname_a = osa.str();
newname_a = nsa.str();
osb.str(string());
osb << dr2 << "\\" << b[k];
nsb.str(string());
nsb << dr2 << "\\" << l - 1 << ". " << b[k];
oldname_b = osb.str();
newname_b = nsb.str();
rename(oldname_a.c_str(), newname_a.c_str())
rename(oldname_b.c_str(), newname_b.c_str())
break;
}
}
}
return 0;
}
Presently the code is set such that it shows me how the comparison between the filenames is made.
It turns out I was not debugging properly, and the problem was in this part of the code:
int c = a[l][20] * 10 + a[l][21];
int d = b[k][14] * 10 + b[k][15];
int e = a[l][17] * 10 + a[l][18];
int f = b[k][11] * 10 + b[k][12];
I did not know that I couldn't assign an integer from a string/char directly to an int. I converted the char to int (which would give me the ASCII value of the char) and then subtracted it by 48 to convert it to decimal (I do not know if there is an easier way to do this, but this seemed to have worked for me!) The modified part looks like this:
c = ((int)a[l][20] - 48) * 10 + ((int)a[l][21] - 48);
d = ((int)b[k][14] - 48) * 10 + ((int)b[k][15] - 48);
e = ((int)a[l][17] - 48) * 10 + ((int)a[l][18] - 48):
f = ((int)b[k][11] - 48) * 10 + ((int)b[k][12] - 48);
There was also a small manual error in the conditions, which I also rectified.

Htoi incorrect output at 10 digits

When I input
0x123456789
I get incorrect outputs, I can't figure out why. At first I thought it was a max possible int value problem, but I changed my variables to unsigned long and the problem was still there.
#include <iostream>
using namespace std;
long htoi(char s[]);
int main()
{
cout << "Enter Hex \n";
char hexstring[20];
cin >> hexstring;
cout << htoi(hexstring) << "\n";
}
//Converts string to hex
long htoi(char s[])
{
int charsize = 0;
while (s[charsize] != '\0')
{
charsize++;
}
int base = 1;
unsigned long total = 0;
unsigned long multiplier = 1;
for (int i = charsize; i >= 0; i--)
{
if (s[i] == '0' || s[i] == 'x' || s[i] == 'X' || s[i] == '\0')
{
continue;
}
if ( (s[i] >= '0') && (s[i] <= '9') )
{
total = total + ((s[i] - '0') * multiplier);
multiplier = multiplier * 16UL;
continue;
}
if ((s[i] >= 'A') && (s[i] <= 'F'))
{
total = total + ((s[i] - '7') * multiplier); //'7' equals 55 in decimal, while 'A' equals 65
multiplier = multiplier * 16UL;
continue;
}
if ((s[i] >= 'a') && (s[i] <= 'f'))
{
total = total + ((s[i] - 'W') * multiplier); //W equals 87 in decimal, while 'a' equals 97
multiplier = multiplier * 16UL;
continue;
}
}
return total;
}
long probably is 32 bits on your computer as well. Try long long.
You need more than 32 bits to store that number. Your long type could well be as small as 32 bits.
Use a std::uint64_t instead. This is always a 64 bit unsigned type. If your compiler doesn't support that, use a long long. That must be at least 64 bits.
The idea follows the polynomial nature of a number. 123 is the same as
1*102 + 2*101 + 3*100
In other words, I had to multiply the first digit by ten two times. I had to multiply 2 by ten one time. And I multiplied the last digit by one. Again, reading from left to right:
Multiply zero by ten and add the 1 → 0*10+1 = 1.
Multiply that by ten and add the 2 → 1*10+2 = 12.
Multiply that by ten and add the 3 → 12*10+3 = 123.
We will do the same thing:
#include <cctype>
#include <ciso646>
#include <iostream>
using namespace std;
unsigned long long hextodec( const std::string& s )
{
unsigned long long result = 0;
for (char c : s)
{
result *= 16;
if (isdigit( c )) result |= c - '0';
else result |= toupper( c ) - 'A' + 10;
}
return result;
}
int main( int argc, char** argv )
{
cout << hextodec( argv[1] ) << "\n";
}
You may notice that the function is more than three lines. I did that for clarity. C++ idioms can make that loop a single line:
for (char c : s)
result = (result << 4) | (isdigit( c ) ? (c - '0') : (toupper( c ) - 'A' + 10));
You can also do validation if you like. What I have presented is not the only way to do the digit-to-value conversion. There exist other methods that are just as good (and some that are better).
I do hope this helps.
I found out what was happening, when I inputted "1234567890" it would skip over the '0' so I had to modify the code. The other problem was that long was indeed 32-bits, so I changed it to uint64_t as suggested by #Bathsheba. Here's the final working code.
#include <iostream>
using namespace std;
uint64_t htoi(char s[]);
int main()
{
char hexstring[20];
cin >> hexstring;
cout << htoi(hexstring) << "\n";
}
//Converts string to hex
uint64_t htoi(char s[])
{
int charsize = 0;
while (s[charsize] != '\0')
{
charsize++;
}
int base = 1;
uint64_t total = 0;
uint64_t multiplier = 1;
for (int i = charsize; i >= 0; i--)
{
if (s[i] == 'x' || s[i] == 'X' || s[i] == '\0')
{
continue;
}
if ( (s[i] >= '0') && (s[i] <= '9') )
{
total = total + ((uint64_t)(s[i] - '0') * multiplier);
multiplier = multiplier * 16;
continue;
}
if ((s[i] >= 'A') && (s[i] <= 'F'))
{
total = total + ((uint64_t)(s[i] - '7') * multiplier); //'7' equals 55 in decimal, while 'A' equals 65
multiplier = multiplier * 16;
continue;
}
if ((s[i] >= 'a') && (s[i] <= 'f'))
{
total = total + ((uint64_t)(s[i] - 'W') * multiplier); //W equals 87 in decimal, while 'a' equals 97
multiplier = multiplier * 16;
continue;
}
}
return total;
}