How to extract particular digits from numbers? - c++

I have BYTE bMins = 36; and I want bMin1 = 3; and bMin2 = 6;
Is it possible without long switches, etc.?
I've already tried it with case, but that's very slow.

Integer division and modulo help:
BYTE bMins = 36;
BYTE bMin1 = bMins / 10;
BYTE bMin2 = bMins % 10;

Here is a demonstrative program
#include <iostream>
#include <cstdlib>
int main()
{
typedef unsigned char BYTE;
BYTE bMins = 36;
BYTE bMin1, bMin2;
auto d = std::div( bMins, 10 );
bMin1 = d.quot;
bMin2 = d.rem;
std::cout << "bMin1 = " << ( int )bMin1 << ", bMin2 = " << ( int )bMin2 << std::endl;
}
The program output is
bMin1 = 3, bMin2 = 6

An alternative way is to convert to a string and use the digit characters:
BYTE bMins = 36;
std::string s = std::to_string(bMins);
BYTE bMin1 = s[0] - '0';
BYTE bMin2 = s[1] - '0';

Related

How to take input 128 bit unsigned integer in c++

I am new to c++. I want to take input a unsigned 128 bit integer using scanf and print it using printf. As I am new to c++ , I only know these two methods for input output. Can someone help me out?
You could use boost, but this library set must be installed yourself:
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>
int main()
{
using namespace boost::multiprecision;
uint128_t v = 0;
std::cin >> v; // read
std::cout << v << std::endl; // write
return 0;
}
If you want to get along without boost, you can store the value into two uint64_t as such:
std::string input;
std::cin >> input;
uint64_t high = 0, low = 0, tmp;
for(char c : input)
{
high *= 10;
tmp = low * 10;
if(tmp / 10 != low)
{
high += ((low >> 32) * 10 + ((low & 0xf) * 10 >> 32)) >> 32;
}
low = tmp;
tmp = low + c - '0';
high += tmp < low;
low = tmp;
}
Printing then, however, gets more ugly:
std::vector<uint64_t> v;
while(high | low)
{
uint64_t const pow10 = 100000000;
uint64_t const mod = (((uint64_t)1 << 32) % pow10) * (((uint64_t)1 << 32) % pow10) % pow10;
tmp = high % pow10;
uint64_t temp = tmp * mod % pow10 + low % pow10;
v.push_back((tmp * mod + low) % pow10);
low = low / pow10 + tmp * 184467440737 + tmp * /*0*/9551616 / pow10 + (temp >= pow10);
high /= pow10;
}
std::vector<uint64_t>::reverse_iterator i = v.rbegin();
while(i != v.rend() && *i == 0)
{
++i;
}
if(i == v.rend())
{
std::cout << 0;
}
else
{
std::cout << *i << std::setfill('0');
for(++i; i != v.rend(); ++i)
{
std::cout << std::setw(8) << *i;
}
}
Above solution works up to (including)
340282366920938463463374516198409551615
= 0x ffff ffff ffff ffff ffff ad06 1410 beff
Above, there is an error.
Note: pow10 can be varied, then some other constants need to be adjusted, e. g. pow10 = 10:
low = low / pow10 + tmp * 1844674407370955161 + tmp * 6 / pow10 + (temp >= pow10);
and
std::cout << std::setw(1) << *i; // setw also can be dropped in this case
Increasing results in reducing the maximum number for which printing still works correctly, decreasing raises the maximum. With pow10 = 10, maximum is
340282366920938463463374607431768211425
= ffff ffff ffff ffff ffff ffff ffff ffe1
I don't know where the error for the very highest numbers comes from, yet, possibly some unconsidered overflow. Any suggestions appreciated, then I'll improve the algorithm. Until then, I'd reduce pow10 to 10 and introduce a special handling for the highest 30 failing numbers:
std::string const specialValues[0] = { /*...*/ };
if(high == 0xffffffffffffffff && low > 0xffffffffffffffe1)
{
std::cout << specialValues[low - 0xffffffffffffffe2];
}
else
{
/* ... */
}
So at least, we can handle all valid 128-bit values correctly.
You can try from_string_128_bits and to_string_128_bits with 128 bits unsigned integers in C :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
__uint128_t from_string_128_bits(const char *str) {
__uint128_t res = 0;
for (; *str; res = res * 10 + *str++ - '0');
return res;
}
static char *to_string_128_bits(__uint128_t num) {
__uint128_t mask = -1;
size_t a, b, c = 1, d;
char *s = malloc(2);
strcpy(s, "0");
for (mask -= mask / 2; mask; mask >>= 1) {
for (a = (num & mask) != 0, b = c; b;) {
d = ((s[--b] - '0') << 1) + a;
s[b] = "0123456789"[d % 10];
a = d / 10;
}
for (; a; s = realloc(s, ++c + 1), memmove(s + 1, s, c), *s = "0123456789"[a % 10], a /= 10);
}
return s;
}
int main(void) {
__uint128_t n = from_string_128_bits("10000000000000000000000000000000000001");
n *= 7;
char *s = to_string_128_bits(n);
puts(s);
free(s); // string must be freed
// print 70000000000000000000000000000000000007
}

Hill Cipher Encrypt

So I am trying to use the hill cipher to encrypt my 3x3 matrix with a given key. It works correctly for the first value outputting n which it should, but then after that value I get large values and it never takes the mod of them. I added the cout statements to help me debug and see what's going wrong, but I still can't fix it. Also the second mod 26 is there because when I didn't have it there I was getting negative 13 instead of positive 13. This is a homework program, our key was given to us as numbers in case that is of any importance.
#include <iostream>
#include <string>
#include <stdio.h>
#include <ctype.h>
using std::endl;
using std::string;
void inverse_matrix();
string encryption(string x);
int main()
{
std::string one = "paymoremoney";
// inverse_matrix();
encryption(one);
system("pause");
return 0;
}
string encryption(string x)
{
int encrypted[4][4];
int key[3][3];
key[0][0] = 4;
key[0][1] = 9;
key[0][2] = 15;
key[1][0] = 15;
key[1][1] = 17;
key[1][2] = 6;
key[2][0] = 24;
key[2][1] = 0;
key[2][2] = 17;
int test = 0;
char str[] = "";
char c;
int length = (int)x.length();
for (int i = 0; i < length; i++)
{
x[i] = tolower(x[i]);
}
/*
while (str[test])
{
c = str[test];
putchar(tolower(c));
test++;
}
*/
int encrypt[4][4];
encrypt[0][0] = x[0];
encrypt[0][1] = x[1];
encrypt[0][2] = x[2];
encrypt[1][0] = x[3];
encrypt[1][1] = x[4];
encrypt[1][2] = x[5];
encrypt[2][0] = x[6];
encrypt[2][1] = x[7];
encrypt[2][2] = x[8];
encrypt[3][0] = x[9];
encrypt[3][1] = x[10];
encrypt[3][2] = x[11];
encrypted[0][0] = (key[0][0] * encrypt[0][0]) + (key[1][0] * encrypt[0][1]) + (key[3][0] * encrypt[0][2]) % 26;
encrypted[0][0] %= 26;
encrypted[0][1] = (key[0][1] * encrypt[0][0]) + (key[1][1] * encrypt[0][1]) + (key[2][1] * encrypt[0][2])%26;
encrypted[0][0] %= 26;
encrypted[0][2] = (key[0][2] * encrypt[0][0]) + (key[1][2] * encrypt[0][1]) + (key[2][2] * encrypt[0][2]) % 26;
encrypted[0][0] %= 26;
std::cout << encrypted[0][0];
std::cout << endl;
std::cout << encrypted[0][1];
std::cout << endl;
std::cout << encrypted[0][2];
std::cout << endl;
}
As this is homework, I'll point in the right direction rather than give a direct answer. You're assigning to encrypted[0][1]. What do you do with that value after assigning to it?

CString Hex value conversion to Byte Array

I have been trying to carry out a conversion from CString that contains Hex string to a Byte array and have been
unsuccessful so far. I have looked on forums and none of them seem to help so far. Is there a function with just a few
lines of code to do this conversion?
My code:
BYTE abyData[8]; // BYTE = unsigned char
CString sByte = "0E00000000000400";
Expecting:
abyData[0] = 0x0E;
abyData[6] = 0x04; // etc.
You can simply gobble up two characters at a time:
unsigned int value(char c)
{
if (c >= '0' && c <= '9') { return c - '0'; }
if (c >= 'A' && c <= 'F') { return c - 'A' + 10; }
if (c >= 'a' && c <= 'f') { return c - 'a' + 10; }
return -1; // Error!
}
for (unsigned int i = 0; i != 8; ++i)
{
abyData[i] = value(sByte[2 * i]) * 16 + value(sByte[2 * i + 1]);
}
Of course 8 should be the size of your array, and you should ensure that the string is precisely twice as long. A checking version of this would make sure that each character is a valid hex digit and signal some type of error if that isn't the case.
How about something like this:
for (int i = 0; i < sizeof(abyData) && (i * 2) < sByte.GetLength(); i++)
{
char ch1 = sByte[i * 2];
char ch2 = sByte[i * 2 + 1];
int value = 0;
if (std::isdigit(ch1))
value += ch1 - '0';
else
value += (std::tolower(ch1) - 'a') + 10;
// That was the four high bits, so make them that
value <<= 4;
if (std::isdigit(ch2))
value += ch1 - '0';
else
value += (std::tolower(ch1) - 'a') + 10;
abyData[i] = value;
}
Note: The code above is not tested.
You could:
#include <stdint.h>
#include <sstream>
#include <iostream>
int main() {
unsigned char result[8];
std::stringstream ss;
ss << std::hex << "0E00000000000400";
ss >> *( reinterpret_cast<uint64_t *>( result ) );
std::cout << static_cast<int>( result[1] ) << std::endl;
}
however take care of memory management issues!!!
Plus the result is in the reverse order as you would expect, so:
result[0] = 0x00
result[1] = 0x04
...
result[7] = 0x0E

How can I pad my md5 message with c/c++

I'm working on a program in c++ to do md5 checksums. I'm doing this mainly because I think I'll learn a lot of different things about c++, checksums, OOP, and whatever else I run into.
I'm having trouble the check sums and I think the problem is in the function padbuff which does the message padding.
#include "HashMD5.h"
int leftrotate(int x, int y);
void padbuff(uchar * buffer);
//HashMD5 constructor
HashMD5::HashMD5()
{
Type = "md5";
Hash = "";
}
HashMD5::HashMD5(const char * hashfile)
{
Type = "md5";
std::ifstream filestr;
filestr.open(hashfile, std::fstream::in | std::fstream::binary);
if(filestr.fail())
{
std::cerr << "File " << hashfile << " was not opened.\n";
std::cerr << "Open failed with error ";
}
}
std::string HashMD5::GetType()
{
return this->Type;
}
std::string HashMD5::GetHash()
{
return this->Hash;
}
bool HashMD5::is_open()
{
return !((this->filestr).fail());
}
void HashMD5::CalcHash(unsigned int * hash)
{
unsigned int *r, *k;
int r2[4] = {0, 4, 9, 15};
int r3[4] = {0, 7, 12, 19};
int r4[4] = {0, 4, 9, 15};
uchar * buffer;
int bufLength = (2<<20)*8;
int f,g,a,b,c,d, temp;
int *head;
uint32_t maxint = 1<<31;
//Initialized states
unsigned int h[4]{ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
r = new unsigned int[64];
k = new unsigned int[64];
buffer = new uchar[bufLength];
if(r==NULL || k==NULL || buffer==NULL)
{
std::cerr << "One of the dyn alloc failed\n";
}
// r specifies the per-round shift amounts
for(int i = 0; i<16; i++)
r[i] = 7 + (5 * ((i)%4) );
for(int i = 16; i < 32; i++)
r[i] = 5 + r2[i%4];
for(int i = 32; i< 48; i++)
r[i] = 4 + r3[i%4];
for(int i = 48; i < 63; i++)
r[i] = 6 + r4[i%4];
for(int i = 0; i < 63; i++)
{
k[i] = floor( fabs( sin(i + 1)) * maxint);
}
while(!(this->filestr).eof())
{
//Read in 512 bits
(this->filestr).read((char *)buffer, bufLength-512);
padbuff(buffer);
//The 512 bits are now 16 32-bit ints
head = (int *)buffer;
for(int i = 0; i < 64; i++)
{
if(i >=0 && i <=15)
{
f = (b & c) | (~b & d);
g = i;
}
else if(i >= 16 && i <=31)
{
f = (d & b) | (~d & b);
g = (5*i +1) % 16;
}
else if(i >=32 && i<=47)
{
f = b ^ c ^ d;
g = (3*i + 5 ) % 16;
}
else
{
f = c ^ (b | ~d);
g = (7*i) % 16;
}
temp = d;
d = c;
c = b;
b = b + leftrotate((a + f + k[i] + head[g]), r[i]);
a = temp;
}
h[0] +=a;
h[1] +=b;
h[2] +=c;
h[3] +=d;
}
delete[] r;
delete[] k;
hash = h;
}
int leftrotate(int x, int y)
{
return(x<<y) | (x >> (32 -y));
}
void padbuff(uchar* buffer)
{
int lack;
int length = strlen((char *)buffer);
uint64_t mes_size = length % UINT64_MAX;
if((lack = (112 - (length % 128) ))>0)
{
*(buffer + length) = ('\0'+1 ) << 3;
memset((buffer + length + 1),0x0,lack);
memcpy((void*)(buffer+112),(void *)&mes_size, 64);
}
}
In my test program I run this on the an empty message. Thus length in padbuff is 0. Then when I do *(buffer + length) = ('\0'+1 ) << 3;, I'm trying to pad the message with a 1. In the Netbeans debugger I cast buffer as a uint64_t and it says buffer=8. I was trying to put a 1 bit in the most significant spot of buffer so my cast should have been UINT64_MAX. Its not, so I'm confused about how my padding code works. Can someone tell me what I'm doing and what I'm supposed to do in padbuff? Thanks, and I apologize for the long freaking question.
Just to be clear about what the padding is supposed to be doing, here is the padding excerpt from Wikipedia:
The message is padded so that its length is divisible by 512. The padding works as follows: first a single bit, 1, is appended to the end of the message. This is followed by as many zeros as are required to bring the length of the message up to 64 bits fewer than a multiple of 512. The remaining bits are filled up with 64 bits representing the length of the original message, modulo 264.
I'm mainly looking for help for padbuff, but since I'm trying to learn all comments are appreciated.
The first question is what you did:
length % UINT64_MAX doesn't make sense at all because length is in bytes and MAX is the value you can store in UINT64.
You thought that putting 1 bit in the most significant bit would give the maximum value. In fact, you need to put 1 in all bits to get it.
You shift 1 by 3. It's only half the length of the byte.
The byte pointed by buffer is the least significant in little endian. (I assume you have little endian since the debugger showed 8).
The second question how it should work.
I don't know what exactly padbuff should do but if you want to pad and get UINT64_MAX, you need something like this:
int length = strlen((char *)buffer);
int len_of_padding = sizeof(uint64_t) - length % sizeof(uint64_t);
if(len_of_padding > 0)
{
memset((void*)(buffer + length), 0xFF, len_of_padding);
}
You worked with the length of two uint64 values. May be you wanted to zero the next one:
uint64_t *after = (uint64_t*)(buffer + length + len_of_padding);
*after = 0;

filling a string made by new in a function

#include <iostream>
using namespace std;
void generCad(int n, char* cad){
int longi = 1, lastchar, m = n; // calculating lenght of binary string
char actual;
do{
longi++;
n /= 2;
}while(n/2 != 0);
cad = new char[longi];
lastchar = longi - 1;
do{
actual = m % 2;
cad[lastchar] = actual;
m /= 2;
lastchar--;
}while(m/2 != 0);
cout << "Cadena = " << cad;
}
Hi! I'm having a problem here because I need a function that creates a binary string for a number n. I think the process is "good" but cout doesn't print anything, I don't know how to fill the string I've created using the new operator
The code should look like this:
void generCad(int n, char** cad)
{
int m = n, c = 1;
while (m >>= 1) // this divides the m by 2, but by shifting which is faster
c++; // here you counts the bits
*cad = new char[c + 1];
(*cad)[c] = 0; // here you end the string by 0 character
while (n)
{
(*cad)[--c] = n % 2 + '0';
n /= 2;
}
cout << "Cadena = " << *cad;
}
Note that cad is now char ** and not char *. If it is just char * then you do not get the pointer as you expect outside the function. If you do not need the string outside this function, then it may be passed as char *, but then do not forget to delete the cad before you leave the function (good habit ;-))
EDIT:
This code will probably be more readable and do the same:
char * toBin(int n)
{
int m = n, c = 1;
while (m >>= 1) // this divides the m by 2, but by shifting which is faster
c++; // here you counts the bits
char *cad = new char[c + 1];
cad[c] = 0; // here you end the string by 0 character
while (n)
{
cad[--c] = n % 2 + '0';
n /= 2;
}
cout << "Cadena = " << cad;
return cad;
}
int main()
{
char *buff;
buff = toBin(16);
delete [] buff;
return 1;
}
actual contains the numbers 0 and 1, not the characters '0' and '1'. To convert, use:
cad[lastchar] = actual + '0';
Also, since you're using cad as a C string, you need to allocate an extra character and add a NUL terminator.
actual = m % 2;
should be:
actual = m % 2 + '0';