NTL String to ZZ conversion and ZZ to String - c++

So I'm working on a basic RSA decryption program and I'm trying to figure out how to convert between a string and a ZZ. I've looked at the following question: How can i convert a string into a ZZ number?, however, I'm a little confused, and the answer there didn't work for me. My code:
fromBase()
{
string message = "hello world";
ZZ number (INIT_VAL, message.c_str());
cerr << number;
}
Gives me the following output.
bad ZZ input
Aborted
So, I thought, no big deal, I'll just try to find what INIT_VAL is supposed to be and that should give me an idea of where to look. But no such luck, I couldn't find anything that looked like it. I trued it with INIT_VAL_STRUCT as well, and got the following error:
base.cpp: In function âNTL::ZZ fromBase(std::string)â:
base.cpp:24: error: âmessageâ is not a type
base.cpp:24: error: expected â,â or â...â before â.â token
Lastly, I tried the solution posted here: Regarding create a NTL class type thinking I could try some type casting. Here's my code:
ZZ fromBase(string message)
{
ZZ x;
x = conv<ZZ>(message);
return x;
}
This gave me the following:
g++ base.cpp -lntl
base.cpp: In function âNTL::ZZ fromBase(std::string)â:
base.cpp:19: error: expected primary-expression before â>â token
As if I didn't specify a type.
To conclude, I know that INIT_VAL is a constant, but it doesn't seem to be working with something. I sense I've just got a disconnect, but trying to find it isn't easy. Any help would be appreciated, and any references for the NTL would be greatly appreciated. Sorry for the long post!
(Also, NTL is pretty poorly documented, from what I've seen, do you have any sites that may help a newbie to the library?)

You want to convert a string, that actually contains non numeric characters into a number.
There is no canonical number of a string, so you cannot do this in one step. C++ can give you the number of a character, which is the ascii number. You can use this function to get the ascii number of a string:
ZZ stringToNumber(string str)
{
ZZ number = conv<ZZ>(str[0]);
long len = str.length();
for(long i = 1; i < len; i++)
{
number *= 128;
number += conv<ZZ>(str[i]);
}
return number;
}
You get the string back by this function
string numberToString(ZZ num)
{
long len = ceil(log(num)/log(128));
char str[len];
for(long i = len-1; i >= 0; i--)
{
str[i] = conv<int>(num % 128);
num /= 128;
}
return (string) str;
}
If you have some non ascii characters like ö or ß you have to use an other way of converting a character to a number.(But I don't know how exactly this works)

Related

MFC newbie: how to determine if a character is hexadecimal using "FindOneOf()"

I'm new at MFC and I need to do something which sounds extremely simple: determining if a string only contains hexadecimal characters.
For that, I browse through the string (it's a CString) and I verify all characters using the FindOneOf() method, as follows:
int iTest = CString(pszText[i]).FindOneOf((LPCWSTR)"0123456789ABCDEFabcdef");
For some bizarre reason, I always get -1 as a result.
What am I doing wrong?
P.s.1 I prefer not to use the SpanIncluding() method, I find the FindOneOf() quite readable but I don't know how to use it.
P.s.2 Also simple STL seems not to be working: I tried to work with std::isxdigit(pszText[i]) but in order to get this to work, I need to include <locale> and then this function is asking for a second parameter, next to the character I want to check, and a null-pointer is not allowed there (std::isxdigit(pszText[i], nullptr) does not work).
There are several problems in your code:
This is wrong:
int iTest = CString(pszText[i]).FindOneOf(LPCWSTR)"0123456789ABCDEFabcdef");
It should be:
int iTest = CString(pszText[i]).FindOneOf(L"0123456789ABCDEFabcdef");
The cast will simply make the compiler believe that "0123..." is a wide string but it isn't. You need to use the L prefix to indicate that the string is a wide string.
But even then your algorithm won't work because FindOneOf will simply find the first occurrence of any of the characters in the parameter.
Example:
int iTest = CString(L"Z223Zbc").FindOneOf(L"0123456789ABCDEFabcdef");
"Z223Zbc" is obviously not a hexadecimal string, but iTest will contain 1 because the first character of "Z223Zbc" being part of "0123456789ABCDEFabcdef" is '2' and that's at position 1.
iTest will only contain -1 if the string to be tested doesn't contain any hexadecimal characters as for example "xyz".
Therefore this solution is appropriate:
#include <cwctype>
...
WCHAR string[] = L"123abcX";
bool ishexstring = true; // assume the string is a hex string
for (int i = 0; ; i++)
{
WCHAR c = string[i];
if (c == 0)
break; // end of string => we exit the looop
if (!std::iswxdigit(c))
{
ishexstring = false; // c is no hex digit
break; // exit loop
}
}
This algorithm should be put into a function, but I'm leaving this as an exercise for the reader.
Solution using SpanIncluding (less efficient because we need tot construct a temporary CString):
bool ishexstring = CString(string).SpanIncluding(L"0123456789ABCDEFabcdef") == str;

Ogre3d having unique node names error

I am working on city generation for a pcg game of mine. I have a for loop which makes 3 cities in random locations, I assign parentIteration to get that "id" for the city and do the same in the for loop where I make a building
for (int i = 0; i < 3; i++)
{
parentIteration = i;
std::srand(i);
_rootNode = GameManager::getSingletonPtr()->getSceneManager()->getRootSceneNode();
_cityNode = _rootNode->createChildSceneNode("cityNode " + parentIteration);
generateCity(std::rand() % 10000 + 10, std::rand() % 10000 + 10, std::rand() % 11 +1);
}
building
for (int i = 0; i < _numberOfBuildings; i++)
{
childIteration = i;
printf(" parent %d and child %d \n", parentIteration, childIteration);
Ogre::SceneNode* buildingNode = _cityNode->createChildSceneNode("citybuildingNode"+childIteration+parentIteration );
}
However when I try to launch the game it will crash on creating the second city. Saying it already has a name similar to what it is trying to write. Yet my printf clearly show that the numbers at that point are all unique. Anyone know how to resolve this issue? (added picture for proof of output)
The "itybuildingNode" in the error message suggests that
"citybuildingNode"+childIteration+parentIteration
is not working quite the way you wanted.
This is because of a couple things working against you:
"citybuildingNode" is a String Literal, and not a string object. It is litteraly just a bunch of characters in a row terminated by a null character and represented as a const char *, a pointer to that array of characters. It is low-level voodoo, the sort of stuff you might make a string class around. For more information see String Literals
Because it's not a string object, you can't pull any of the usual string object tricks like concatenating with a + and comparing with ==. But because it is a pointer, the compiler interprets + as an attempt to perform pointer arithmetic and reference another location in the array. It compiles, but note how it turned "citybuildingNode" into "itybuildingNode". Oops.
What this looks like is something like:
const char* temp = "citybuildingNode"
_cityNode->createChildSceneNode(temp + childIteration + parentIteration);
which resolves to
const char* temp = "citybuildingNode"
_cityNode->createChildSceneNode(&temp[childIteration + parentIteration]);
Even if it was a string object, the C++ standard string object, std::string does not allow you to add numbers to strings. It only adds strings together to build a bigger string. To add a number to a std::string, you have to turn the number into a std::string. std::to_string can help you here, but there is a cleaner-looking way to do this with std::stringstream
Eg:
std::stringstream nodename("citybuildingNode");
// builds a string stream around the string literal
nodename << childIteration << parentIteration;
// writes the numbers into the stream the same way `cin << number;` would
// turning the number into a string for you
Ogre::SceneNode* buildingNode = _cityNode->createChildSceneNode(nodename.str());
// gets the assembled string from the stringstream
// null-terminated string like ogre expects
This gets you started in the right direction, but still allows for collision between child 1 and parent 10 ("citybuildingNode110") and child 11 and parent 0 (also "citybuildingNode110") and similar. So you really want something more like
nodename << childIteration << '_' << parentIteration;
to force a separator between the two numbers.
Documentation for std::stringstream.
There is also another possible nasty. The string we just supplied to ogre will only exist for as long as std::stringstream nodename exists and it will die at the end of the loop that generates it. I do not see anything in a quick perusal of the documentation that says ogre makes its own copy of this string. So play around a bit to make sure that you don't have to store this name somewhere to prevent it from falling out of scope, being destroyed, and leaving ogre with a dangling reference.

Sum of char and int leads to weird char in my c++ code

I tried searching for a solution online but I could not find one. The closet I came is this A similar unanswered question on cplusplus.com
Here is my code....
int main()
{
char a[1000000],s[100000];
scanf("%s",s);
int i,l=strlen(s);
//cout<<l;
for(int i=0;i<l;i++)
a[i]=s[l-i-1]; //to reverse the word in s[]
cout<<a<<endl;
for(i=0;i<l;i++)
{
s[i]+=a[i]-96;
if(s[i]>'z')
{
int diff=s[i]-'z';
s[i]='a'+(diff-1);
}
}
cout<<s;
return 0;
}
//l=length of string.
//a[i]=is another string with word in s[] being reversed.
My problem is that when I execute this and give an input , say, world it prints some weird characters.
I am unable to see any fault in the logic I applied and I feel frustrated now.
The question asked was that I am supposed to add two strings one of which is reversed version of the other one and that the addition is to be performed in such a way that 'a' + 'b' = 'c' , 'd' + 'a' = 'e' .... and 'z' + 'a' = 'a'. So that the addition is closed under small-alphabets.
Your problem is that you're using a signed char (a signed byte). When the signed char goes over 127, then it flips negative. This causes your computation to miss the fact that the value is out of range, and when it's printed it's converted back to a high character.
You can simply replace your wrap around check with this:
while ((unsigned char)s[i] > 'z')
{
s[i] -= 26;
}
And then your program at least does what you wanted it to do. There are good suggestions in the comments for making it more robust as well.

C++, Trouble with string and int conversion

I know how to convert the string when it's just made up of integers, or it begins with ints. I am trying to convert to an integer when the string starts with a char in the beginning, or middle. I've tried running through a for loop, checking if (isdigit(str[i]) before trying stoi, stringstream, atoi, etc... None of them really work. I have the same problem even without the for loop. I've tried Googling my problem, but no luck. Any suggestions, or anything that I can try?
You have to check character by character if it's a digit or not and, if it is, add it to a new string. In the end, you convert your new string to an int like you would normally. Look at the code below. Hope I could help!
string s = "pc2jjj10";
char temp;
string result;
for (int i = 0; i < s.length(); i++){
temp = s.at(i);
if (isdigit(temp)){
result.push_back(temp);
}
}
int number = stoi(result);

vector subscript out of range C++ (substring)

So I'm having this problem with substrings and converting them into integers. This will probably be an easy-fix but I'm not managing to find the answer.
So I receive this string "12-12-2012" and i want to split it, convert into integers and call the modifications methods like this:
string d = (data.substr(0,data.find("-")));
setDia(atoi(d.c_str()));
But it gives me the error mentioned in the title when I try to comvert into an integer.
EDIT:
Turns out that the string doesn't actually contain a '-' but this is really confusing since the string in the parameter results from this : to_char(s.diaInicio,'dd-mm-yyyy')
More information: I used the debugger and it's making the split correctly since the value that atoi receives is 12 (the first split). But I don't know why the VS can't convert into an integer even though the string passed is "12".
This code is not save in the sense that it fails when data does not contain a -.
Try this:
std::size_t p = data.find("-");
if(p == std::string::npos) {
// ERROR no - in string!
}
else {
std::string d = data.substr(0,p);
setDia(atoi(d.c_str()));
}
Please duplicate the problem with a very simple program. If what you say is correct, then the following program should also fail (taken from Danvil's example, and without calling the unknown (to us) setDia() function):
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
string data = "12-12-2012";
std::size_t p = data.find("-");
if(p == std::string::npos) {
// ERROR no - in string!
}
else {
std::string d = data.substr(0,p);
atoi(d.c_str());
}
}