String rotator in C++ (bitwise rotation) - c++

I have string array which has 8 field. 8 bits per field give me 64 bits of memory in single string this type. I want to create rotate function for this string array. For simple for string 20 (in HEX) function RotateLeft(string, 1) gives me 40, like in rotate. Max rotate value is 64, then function must return sent string (RotateLeft(string, 64) == string). I need rotate left and right. I try to create something like this:
std::string RotateLeft(std::string Message, unsigned int Value){
std::string Output;
unsigned int MessageLength = Message.length(), Bit;
int FirstPointer, SecondPointer;
unsigned char Char;
for (int a = 0; a < MessageLength; a++){
FirstPointer = a - ceil(Value / 8.);
if (FirstPointer < 0){
FirstPointer += MessageLength;
}
SecondPointer = (FirstPointer + 1) % MessageLength;
Bit = Value % 8;
Char = (Message[FirstPointer] << Bit) | (Message[SecondPointer] & (unsigned int)(pow(2, Bit) - 1));
Output += Char;
}
return Output;
}
It working for value 64, but not for other values. For simple for HEX string (function get string elements as decimal values but it is for better reading) when I sent this value: 243F6A8885A308D3 and execute RotateLeft(string, 1) I received A6497ED4110B4611. When I check this in Windows Calc it now valid value. Anyone can help me and show where I do mistake?

I am not sure if I correctly understand what you want to do, but somehow to me it looks like you are doing something rather simple in a complicated way. When shifting numbers, I would not put them in a string. However, once you have it as a string, you could do this:
std::string rotate(std::string in,int rot){
long long int number;
std::stringstream instream(in);
instream >> number;
for (int i=0;i<rot;i++){number *= 2;}
std::stringstream outstream;
outstream << number;
return outstream.str();
}
...with a small modification to allow also negative shifts.

You have a hex value in a string, you want to rotate it as if it was actually a number. You could just change it to an actual number, then back into a string:
// Some example variables.
uint64_t x, shift = 2;
string in = "fffefffe", out;
// Get the string as a number
std::stringstream ss;
ss << std::hex << in;
ss >> x;
// Shift the number
x = x << shift;
// Convert the number back into a hex string
std::ostringstream ss2;
ss2 << std::hex << x;
// Get your output.
out = ss2.str();
Here is a live example.

Related

Converting string hexadecmials to unsigned char (BYTE) in C

I want to convert the hexadecimal string value 0x1B6 to unsigned char - where it will store the value in the format 0x1B, 0x60 We had achieved the scenarios in C++, but C doesn't support std::stringstream.
The following code is C++, how do I achieve similar behavior in C?
char byte[2];
std::string hexa;
std::string str = "0x1B6" // directly assigned the char* value in to string here
int index =0;
unsigned int i;
for(i = 2; i < str.length(); i++) {
hexa = "0x"
if(str[i + 1] !NULL) {
hexa = hexa + str[i] + str[i + 1];
short temp;
std::istringstream(hexa) >> std::hex >> temp;
byte[index] = static_cast<BYTE>(temp);
} else {
hexa = hexa+ str[i] + "0";
short temp;
std::istringstream(hexa) >> std::hex >> temp;
byte[index] = static_cast<BYTE>(temp);
}
}
output:
byte[0] --> 0x1B
byte[1]--> 0x60
I don't think your solution is very efficient. But disregarding that, with C you would use strtol. This is an example of how to achieve something similar:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void) {
const char *hex_string = "0x1B60";
long hex_as_long = strtol(hex_string, NULL, 16);
printf("%lx\n", hex_as_long);
// From right to left
for(int i = 0; i < strlen(&hex_string[2]); i += 2) {
printf("%x\n", (hex_as_long >> (i * 4)) & 0xff);
}
printf("---\n");
// From left to right
for(int i = strlen(&hex_string[2]) - 2; i >= 0; i -= 2) {
printf("%x\n", (hex_as_long >> (i * 4)) & 0xff);
}
}
So here we get the full value as a long inside hex_as_long. We then print the whole long with the first print and the individual bytes inside the second for loop. We are shifting multiples of 4 bits because one hex digit (0xf) covers exactly 4 bits of data.
To get the bytes or the long printed to a string rather than to stdout (if that is what you want to achieve), you can use strprintf or strnprintf in a similar way to how printf is used, but with a variable or array as destination.
This solution scans whole bytes (0xff) at a time. If you need to handle one hex digit (0xf) at a time you can divide all the operations by two and mask with 0xf instead of 0xff.

Need help encoding C++ strings by increasing ASCII value

I've looked around everywhere for a C++ code that takes a message from the user, and encodes it by increasing the ASCII value of each character (obviously not very secure, but simple enough). I've managed to put together a program that returns a character of a few values higher, but can not figure out how to do it with a full message including spaces. I plan to make a decoder that does the opposite afterwards. Any help would be really appreciated. Thanks in advance.
Single Value C++ Program -
#include <iostream>
using namespace std;
int main(){
char ascii;
cout << "Enter a character: ";
cin >> ascii;
cout << "Its ascii value is: " << (int) ascii << endl;
return 0;
}
Working Encoder Example in VBS -
set x = WScript.CreateObject("WScript.Shell")
entxtde = inputbox("Enter text to be encoded")
entxtde = StrReverse(entxtde)
x.Run "%windir%\notepad"
wscript.sleep 1000
x.sendkeys encode(entxtde)
function encode(s)
For i = 1 To Len(s)
newtxt = Mid(s, i, 1)
newtxt = Chr(Asc(newtxt)+3)
coded = coded & newtxt
Next
encode = coded
End Function
std::string originalString = "";
std::string newString = "";
int incrementValue = 1;
std::cout << "Input a string to encode: ";
std::cin >> originalString;
for(int i = 0; i < originalString.length(); i++) {
newString += (originalString.at(i) + incrementValue);
}
std::cout >> "New string is " + newString
Just change incrementValue to change how it's encoded.
"Hello" = "Ifmmp" if incrementValue = 1
To reverse it, just change it to subtract incrementValue instead of add in the same kind of for loop. Simple enough I think
This may be done in a single line, or two if you want to stay under 80 columns. Where value is the string you wish to encrypt, and offset the offset value:
auto caesar = [offset](CharT c){return c + offset;};
std::transform(value.begin(), value.end(), value.begin(), caesar);
For bonus points you can make it work with any kind of string by templating on character type:
template <typename CharT>
std::basic_string<CharT> caesarEncode(std::basic_string<CharT> value, CharT offset){
auto caesar = [offset](CharT c){return c + offset;};
std::transform(value.begin(), value.end(), value.begin(), caesar);
return value;
}
Since it looks like you may be experiencing difficulties actually obtaining a string with whitespace, you may get one using the getline function of the standard library, which by default obtains one full line of the source stream.
// narrow (CharT = char)
std::string value;
std::getline(std::cin, value);
// wide (CharT = wchar_t)
std::wstring wvalue;
std::getline(std::wcin, wvalue);
for which actually encoding the string would be done as follows:
char offset = 12;
auto encoded = caesarEncode(value, offset);
wchar_t woffset = 12;
auto wencoded = caesarEncode(wvalue, woffset);
You can see an example in practice here on coliru.
It's simple really. First you take your input as a string. Then, iterate through each character adding by what you want. To ensure the value remains valid and easy to reverse, you mod that value by the max value of a char, i.e. 255.
int main () {
std::string input; // to store the text
std::getline(std::cin, input); // get the text
const int _add = 12; // value added
const int max_size = 255; // max value of a char
for (int i = 0; i < input.size(); ++i)
input[i] = (input[i] + _add) % max_size;
/* now the input is properly modified */
}
note: _add is an int to prevent overflow errors.

Conversion from Integer to BCD

I want to convert the integer (whose maximum value can reach to 99999999) in to BCD and store in to array of 4 characters.
Like for example:
Input is : 12345 (Integer)
Output should be = "00012345" in BCD which is stored in to array of 4 characters.
Here 0x00 0x01 0x23 0x45 stored in BCD format.
I tried in the below manner but didnt work
int decNum = 12345;
long aux;
aux = (long)decNum;
cout<<" aux = "<<aux<<endl;
char* str = (char*)& aux;
char output[4];
int len = 0;
int i = 3;
while (len < 8)
{
cout <<"str: " << len << " " << (int)str[len] << endl;
unsigned char temp = str[len]%10;
len++;
cout <<"str: " << len << " " << (int)str[len] << endl;
output[i] = ((str[len]) << 4) | temp;
i--;
len++;
}
Any help will be appreciated
str points actually to a long (probably 4 bytes), but the iteration accesses 8 bytes.
The operation str[len]%10 looks as if you are expecting digits, but there is only binary data. In addition I suspect that i gets negative.
First, don't use C-style casts (like (long)a or (char*)). They are a bad smell. Instead, learn and use C++ style casts (like static_cast<long>(a)), because they point out where you are doing things that are dangeruos, instead of just silently working and causing undefined behavior.
char* str = (char*)& aux; gives you a pointer to the bytes of aux -- it is actually char* str = reinterpret_cast<char*>(&aux);. It does not give you a traditional string with digits in it. sizeof(char) is 1, sizeof(long) is almost certainly 4, so there are only 4 valid bytes in your aux variable. You proceed to try to read 8 of them.
I doubt this is doing what you want it to do. If you want to print out a number into a string, you will have to run actual code, not just reinterpret bits in memory.
std::string s; std::stringstream ss; ss << aux; ss >> s; will create a std::string with the base-10 digits of aux in it.
Then you can look at the characters in s to build your BCD.
This is far from the fastest method, but it at least is close to your original approach.
First of all sorry about the C code, I was deceived since this started as a C questions, porting to C++ should not really be such a big deal.
If you really want it to be in a char array I'll do something like following code, I find useful to still leave the result in a little endian format so I can just cast it to an int for printing out, however that is not strictly necessary:
#include <stdio.h>
typedef struct
{
char value[4];
} BCD_Number;
BCD_Number bin2bcd(int bin_number);
int main(int args, char **argv)
{
BCD_Number bcd_result;
bcd_result = bin2bcd(12345678);
/* Assuming an int is 4 bytes */
printf("result=0x%08x\n", *((int *)bcd_result.value));
}
BCD_Number bin2bcd(int bin_number)
{
BCD_Number bcd_number;
for(int i = 0; i < sizeof(bcd_number.value); i++)
{
bcd_number.value[i] = bin_number % 10;
bin_number /= 10;
bcd_number.value[i] |= bin_number % 10 << 4;
bin_number /= 10;
}
return bcd_number;
}

how do I convert an integer which is defined in an int array to hex?

I have an int array that represents a very large number such as:
// ...
unsigned int n1[200];
// ...
n1 = {1,3,4,6,1,...} ==> means my number is 13461...
How can I convert that large number to its hex value?
So here is my take on the problem:
You have an array of digits.
You want to build an unsigned int from this array of digits.
The array of digits could be either HEX digits, or DECIMAL digits.
To build this unsigned long long, assuming an array of DECIMAL digits:
unsigned long long myNum = 0;
unsigned int n1[200];
for (int i=0; i < n1.length ; i++ ){
myNum += pow(10,i) * n1[n1.length - i];
}
To build this unsigned long long, assuming an array of HEX digits:
for (int i=0; i < n1.length ; i++ ){
myNum += pow(16,i)* n1[n1.length - i];
}
(Notice the base 16)
Disclaimer: limited to exactly 16 digits MAX stored in your array. After that you will overrun the buffer
If it is just a matter of DISLAYING the number in the correct format...
Well, an int is an int is an int... (in memory).
There are 10 fingers on my hands whether or not I call that number 10, or A.
If you want to format the number for DISPLAY in hex, then try something like:
unsigned int i = 10;
//OR
unsigned int i = 0xA;
printf("My number in hex: %x", i);
printf("My number in decimal: %d", i);
I'm unsure if you want the hexadecimal represented as a string. If that's
the case, here's some code:
#include <iostream>
#include <stack>
using namespace std;
string toHexa(int num){
string digit = "0123456789ABCDEF", numStr = "";
stack<char> s;
do {
s.push(digit[num%16]);
num /= 16;
} while (num != 0);
while (!s.empty()){
numStr += s.top();
s.pop();
}
return numStr;
}
int main(){
int num = 235; // EB in hexa
cout << num << " to hexadecimal: " << toHexa(num) << endl;
return 0;
}
You could use the GMP library to make this relatively straightforward.
Use basic_stringstream<unsigned int> to wrap your array.
Use operator << to read it into a mpz_t variable.
Create another basic_stringstream<unsigned int> for your result.
Use std::hex and operator >> to write the variable back out in hexadecimal.
That would work on ASCII digits, but yours aren't. You can still use GMP, but you'll want to use the mpn_get_str and mpn_set_str functions instead. You'll need to copy your digits into an unsigned char[] and then you can specify the base for conversion to mp_limb_t and back to a string of digits.

How to convert an int to a binary string representation in C++

I have an int that I want to store as a binary string representation. How can this be done?
Try this:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<32> x(23456);
std::cout << x << "\n";
// If you don't want a variable just create a temporary.
std::cout << std::bitset<32>(23456) << "\n";
}
I have an int that I want to first convert to a binary number.
What exactly does that mean? There is no type "binary number". Well, an int is already represented in binary form internally unless you're using a very strange computer, but that's an implementation detail -- conceptually, it is just an integral number.
Each time you print a number to the screen, it must be converted to a string of characters. It just so happens that most I/O systems chose a decimal representation for this process so that humans have an easier time. But there is nothing inherently decimal about int.
Anyway, to generate a base b representation of an integral number x, simply follow this algorithm:
initialize s with the empty string
m = x % b
x = x / b
Convert m into a digit, d.
Append d on s.
If x is not zero, goto step 2.
Reverse s
Step 4 is easy if b <= 10 and your computer uses a character encoding where the digits 0-9 are contiguous, because then it's simply d = '0' + m. Otherwise, you need a lookup table.
Steps 5 and 7 can be simplified to append d on the left of s if you know ahead of time how much space you will need and start from the right end in the string.
In the case of b == 2 (e.g. binary representation), step 2 can be simplified to m = x & 1, and step 3 can be simplified to x = x >> 1.
Solution with reverse:
#include <string>
#include <algorithm>
std::string binary(unsigned x)
{
std::string s;
do
{
s.push_back('0' + (x & 1));
} while (x >>= 1);
std::reverse(s.begin(), s.end());
return s;
}
Solution without reverse:
#include <string>
std::string binary(unsigned x)
{
// Warning: this breaks for numbers with more than 64 bits
char buffer[64];
char* p = buffer + 64;
do
{
*--p = '0' + (x & 1);
} while (x >>= 1);
return std::string(p, buffer + 64);
}
AND the number with 100000..., then 010000..., 0010000..., etc. Each time, if the result is 0, put a '0' in a char array, otherwise put a '1'.
int numberOfBits = sizeof(int) * 8;
char binary[numberOfBits + 1];
int decimal = 29;
for(int i = 0; i < numberOfBits; ++i) {
if ((decimal & (0x80000000 >> i)) == 0) {
binary[i] = '0';
} else {
binary[i] = '1';
}
}
binary[numberOfBits] = '\0';
string binaryString(binary);
http://www.phanderson.com/printer/bin_disp.html is a good example.
The basic principle of a simple approach:
Loop until the # is 0
& (bitwise and) the # with 1. Print the result (1 or 0) to the end of string buffer.
Shift the # by 1 bit using >>=.
Repeat loop
Print reversed string buffer
To avoid reversing the string or needing to limit yourself to #s fitting the buffer string length, you can:
Compute ceiling(log2(N)) - say L
Compute mask = 2^L
Loop until mask == 0:
& (bitwise and) the mask with the #. Print the result (1 or 0).
number &= (mask-1)
mask >>= 1 (divide by 2)
I assume this is related to your other question on extensible hashing.
First define some mnemonics for your bits:
const int FIRST_BIT = 0x1;
const int SECOND_BIT = 0x2;
const int THIRD_BIT = 0x4;
Then you have your number you want to convert to a bit string:
int x = someValue;
You can check if a bit is set by using the logical & operator.
if(x & FIRST_BIT)
{
// The first bit is set.
}
And you can keep an std::string and you add 1 to that string if a bit is set, and you add 0 if the bit is not set. Depending on what order you want the string in you can start with the last bit and move to the first or just first to last.
You can refactor this into a loop and using it for arbitrarily sized numbers by calculating the mnemonic bits above using current_bit_value<<=1 after each iteration.
There isn't a direct function, you can just walk along the bits of the int (hint see >> ) and insert a '1' or '0' in the string.
Sounds like a standard interview / homework type question
Use sprintf function to store the formatted output in the string variable, instead of printf for directly printing. Note, however, that these functions only work with C strings, and not C++ strings.
There's a small header only library you can use for this here.
Example:
std::cout << ConvertInteger<Uint32>::ToBinaryString(21);
// Displays "10101"
auto x = ConvertInteger<Int8>::ToBinaryString(21, true);
std::cout << x << "\n"; // displays "00010101"
auto x = ConvertInteger<Uint8>::ToBinaryString(21, true, "0b");
std::cout << x << "\n"; // displays "0b00010101"
Solution without reverse, no additional copy, and with 0-padding:
#include <iostream>
#include <string>
template <short WIDTH>
std::string binary( unsigned x )
{
std::string buffer( WIDTH, '0' );
char *p = &buffer[ WIDTH ];
do {
--p;
if (x & 1) *p = '1';
}
while (x >>= 1);
return buffer;
}
int main()
{
std::cout << "'" << binary<32>(0xf0f0f0f0) << "'" << std::endl;
return 0;
}
This is my best implementation of converting integers(any type) to a std::string. You can remove the template if you are only going to use it for a single integer type. To the best of my knowledge , I think there is a good balance between safety of C++ and cryptic nature of C. Make sure to include the needed headers.
template<typename T>
std::string bstring(T n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}
Use it like so,
std::cout << bstring<size_t>(371) << '\n';
This is the output in my computer(it differs on every computer),
0000000000000000000000000000000000000000000000000000000101110011
Note that the entire binary string is copied and thus the padded zeros which helps to represent the bit size. So the length of the string is the size of size_t in bits.
Lets try a signed integer(negative number),
std::cout << bstring<signed int>(-1) << '\n';
This is the output in my computer(as stated , it differs on every computer),
11111111111111111111111111111111
Note that now the string is smaller , this proves that signed int consumes less space than size_t. As you can see my computer uses the 2's complement method to represent signed integers (negative numbers). You can now see why unsigned short(-1) > signed int(1)
Here is a version made just for signed integers to make this function without templates , i.e use this if you only intend to convert signed integers to string.
std::string bstring(int n){
std::string s;
for(int m = sizeof(n) * 8;m--;){
s.push_back('0'+((n >> m) & 1));
}
return s;
}