Passing an unsigned char array by reference in C++ - c++

all! I'm running into some difficulty with a school project in which we're implementing the Serpent cipher. The problem is in the function
setKey(unsigned char (&user_key[32]))
I would like to pass a byte array of size 32 to my function, and then have my function do all manner of stuff to the values of that array. My code as I've printed it will not compile, as I get the error -
no known conversion for argument 1 from ‘unsigned char (*)[32]’ to
‘unsigned char (&) [32]’
I've looked through a number of similar posts, and none of the solutions I've found seem to lead to my code compiling, or if it compiles, doing what I'd like it to. Unfortunately, I can't remember how I last got my code to compile, but when I did, printing out the values of user_key[] within the function setKey() gave me the following output:
19, 0, 0, 0, 51, 0, 0, 0, 83, 0, 0, 0, 115, 0, 0, 0, 20, 0, 0, 0, 52, 0, 0, 0,
84, 0, 0, 0, 116, 0, 0, 0
In addition, when it was running, it was exiting with a segfault after printing out the line
"This is the end. My only friend, the end." as well as a "stack smashing detected" warning. In short, my code seems to be all sorts of wrong. Any help would be greatly appreciated!!
#include <iostream>
#include <math.h>
using namespace std;
class KeySchedule{
int ip[64];
int key_size;
unsigned long long int k0;
unsigned long long int k1;
unsigned long long int k2;
unsigned long long int k3;
public:
KeySchedule(){
/*The initial permutation. To be applied to the plaintext and keys.
ip = {0, 32, 64, 96, 1, 33, 65, 97, 2, 34, 66, 98, 3, 35, 67, 99,
4, 36, 68, 100, 5, 37, 69, 101, 6, 38, 70, 102, 7, 39, 71, 103,
8, 40, 72, 104, 9, 41, 73, 105, 10, 42, 74, 106, 11, 43, 75, 107,
12, 44, 76, 108, 13, 45, 77, 109, 14, 46, 78, 110, 15, 47, 79, 111,
16, 48, 80, 112, 17, 49, 81, 113, 18, 50, 82, 114, 19, 51, 83, 115,
20, 52, 84, 116, 21, 53, 85, 117, 22, 54, 86, 118, 23, 55, 87, 119,
24, 56, 88, 120, 25, 57, 89, 121, 26, 58, 90, 122, 27, 59, 91, 123,
28, 60, 92, 124, 29, 61, 93, 125, 30, 62, 94, 126, 31, 63, 95, 127};
*/
for (int i = 0; i < 127; i++ ){
ip[i] = (32*i) % 127;
}
ip[127] = 127;
k3 = 0;
k2 = 0;
k1 = 0;
k0 = 0;
key_size = -1;
}
void setKey (unsigned char (&user_key)[32]){
for (int i = 0; i<32; i++){
cout << (int)(user_key)[i] << endl;
}
for (int i = 0; i<8; i++){
k3 ^= (int)(user_key)[i] << (8-i);
k2 ^= (int)(user_key)[i+8] << (8-i);
k1 ^= (int)(user_key)[i+16] << (8-i);
k0 ^= (int)(user_key)[i+24] << (8-i);
}
}
};
int main(){
unsigned char testkey[]= {0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x10,
0x20, 0x30, 0x40, 0x50,
0x60, 0x70, 0x80, 0x90,
0xa0, 0xb0, 0xc0, 0xd0,
0xe0, 0xf0, 0x00, 0xff};
cout << "The size of testkey is: "
<< sizeof(testkey)/sizeof(*testkey) << endl;
KeySchedule ks = KeySchedule();
ks.setKey(&testkey);
cout << "This is the end. My only friend, the end." << endl;
};

You are passing the address your unsigned char array, i.e. a pointer to unsigned char[32]. You need this:
ks.setKey(testkey);

Related

Inlined function to return nested array value not performing as expected

I want to inline the function MyClass:at(), but performance isn't as I expect.
MyClass.cpp
#include <algorithm>
#include <chrono>
#include <iostream>
#include <vector>
#include <string>
// Making this a lot shorter than in my actual program
std::vector<std::vector<int>> arrarr =
{
{ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48},
{24, 47, 32, 60, 99, 3, 45, 2, 44, 75, 33, 53, 78, 36, 84, 20, 35, 17, 12, 50},
{32, 98, 81, 28, 64, 23, 67, 10, 26, 38, 40, 67, 59, 54, 70, 66, 18, 38, 64, 70},
{67, 26, 20, 68, 2, 62, 12, 20, 95, 63, 94, 39, 63, 8, 40, 91, 66, 49, 94, 21},
{24, 55, 58, 5, 66, 73, 99, 26, 97, 17, 78, 78, 96, 83, 14, 88, 34, 89, 63, 72},
{21, 36, 23, 9, 75, 0, 76, 44, 20, 45, 35, 14, 0, 61, 33, 97, 34, 31, 33, 95},
{78, 17, 53, 28, 22, 75, 31, 67, 15, 94, 3, 80, 4, 62, 16, 14, 9, 53, 56, 92},
{16, 39, 5, 42, 96, 35, 31, 47, 55, 58, 88, 24, 0, 17, 54, 24, 36, 29, 85, 57},
{86, 56, 0, 48, 35, 71, 89, 7, 5, 44, 44, 37, 44, 60, 21, 58, 51, 54, 17, 58},
{19, 80, 81, 68, 5, 94, 47, 69, 28, 73, 92, 13, 86, 52, 17, 77, 4, 89, 55, 40},
{ 4, 52, 8, 83, 97, 35, 99, 16, 7, 97, 57, 32, 16, 26, 26, 79, 33, 27, 98, 66},
{88, 36, 68, 87, 57, 62, 20, 72, 3, 46, 33, 67, 46, 55, 12, 32, 63, 93, 53, 69},
{ 4, 42, 16, 73, 38, 25, 39, 11, 24, 94, 72, 18, 8, 46, 29, 32, 40, 62, 76, 36},
{20, 69, 36, 41, 72, 30, 23, 88, 34, 62, 99, 69, 82, 67, 59, 85, 74, 4, 36, 16},
{20, 73, 35, 29, 78, 31, 90, 1, 74, 31, 49, 71, 48, 86, 81, 16, 23, 57, 5, 54},
{ 1, 70, 54, 71, 83, 51, 54, 69, 16, 92, 33, 48, 61, 43, 52, 1, 89, 19, 67, 48},
};
class MyClass
{
public:
MyClass(std::vector<std::vector<int>> arr) : arr(arr)
{
rows = arr.size();
cols = arr.at(0).size();
}
inline auto at(int row, int col) const { return arr[row][col]; }
void arithmetic(int n) const;
private:
std::vector<std::vector<int>> arr;
int rows;
int cols;
};
MyClass.cpp:
void MyClass::arithmetic(int n) const
{
using std::chrono::high_resolution_clock;
using std::chrono::duration_cast;
using std::chrono::duration;
using std::chrono::milliseconds;
auto t1 = high_resolution_clock::now();
int highest_product = 0;
for (auto y = 0; y < rows; ++y)
{
for (auto x = 0; x < cols; ++x)
{
// Horizontal product
if (x + n < cols)
{
auto product = 1;
for (auto i = 0; i < n; ++i)
{
product *= at(y, x + i);
}
highest_product = std::max(highest_product, product);
}
}
}
auto t2 = high_resolution_clock::now();
duration<double, std::milli> ms_double = t2 - t1;
std::cout << ms_double.count() << "ms\n";
return highestProduct;
};
Now what I want know is why do I get better performance when I replace product *= at(y, x + i); with product *= arr[y][x+i];? When I test it with the first case, the timing on my large array takes roughly 6.7ms, and the second case takes 5.3ms. I thought when I inlined the function, it should be the same implementation as the second case.
Member function directly defined in the class definition (typically in header files) are implicitly inlined so using inline is useless in this case. inline do not guarantee the function is inlined. It is just an hint for the compiler. The keyword is also an important during the link to avoid the multiple-definition issue. Function that are not make inline can still be inlined if the compiler can see the code of the target function (ie. it is in the same translation unit or link time optimization are applied). For more information about this, please read Why are class member functions inlined?
Note that the inlining is typically performed in the optimization step of compilers (eg. -O1//O1). Thus without optimizations, most compilers will not inline the function.
Using std::vector<std::vector<int>> is not efficient since it is not a contiguous data structure and it require 2 indirection to access an item. Two sub-vectors next to each other can be stored far away in memory likely causing more cache misses (and/or thrashing due to the alignment). Please consider using one big flatten array and access items using y*cols+x where cols is the size of the sub-vectors (20 here). Alternatively a int[16][20] data type should do the job well if the size if fixed at compile-time.
MyClass(std::vector<std::vector<int>> arr) cause the input parameter to be copied (and so all the sub-vectors). Please consider using a const std::vector<std::vector<int>>& type.
While at is convenient for checking bounds at runtime, this feature can strongly decrease performance. Consider using the operator [] if you do not need that. You can use assertions combined with flatten arrays so to get a fast code in release and a safe code in debug (you can enable/disable them by defining the NDEBUG macro).

how use ADPCM microchips

I have some problems with adpcm in .wav (sound)files.
at first of this question, I should say that I didn't read all things about ADPCM , just wanted to implement that fast and work on it ... (just training code)
I implemented it from MicroChip's pdf guid adpcm.(it's better to say copy/pasted and edited ,created class)
Test code:
const std::vector<int8_t> data = {
64, 67, 71, 75, 79, 83, 87, 91, 94, 98, 101, 104, 107, 110, 112,
115, 117, 119, 121, 123, 124, 125, 126, 126, 127, 127, 127, 126, 126, 125,
124, 123, 121, 119, 117, 115, 112, 110, 107, 104, 101, 98, 94, 91, 87,
83, 79, 75, 71, 67, 64, 60, 56, 52, 48, 44, 40, 36, 33, 29,
26, 23, 20, 17, 15, 12, 10, 8, 6, 4, 3, 2, 1, 1, 0,
0, 0, 1, 1, 2, 3, 4, 6, 8, 10, 12, 15, 17, 20, 23,
26, 29, 33, 36, 40, 44, 48, 52, 56, 60, 64};
void function() {
std::vector<uint8_t> en;
std::vector<uint8_t> de;
{ // encode
wave::ADPCM adpcm;
// 32768
for (size_t i{0}; i < data.size() - 3; i += 4) {
int16_t first{static_cast<int16_t>(
~((static_cast<uint16_t>(data[i]) & 0xff) |
((static_cast<uint16_t>(data[i + 1]) << 8) & 0xff00)) +
1)};
int16_t second{static_cast<int16_t>(
~((static_cast<uint16_t>(data[i + 2]) & 0xff) |
((static_cast<uint16_t>(data[i + 3]) << 8) & 0xff00)) +
1)};
en.push_back(static_cast<uint8_t>((adpcm.ADPCMEncoder(first) & 0x0f) |
(adpcm.ADPCMEncoder(second) << 4)));
}
}
{ // decode
wave::ADPCM adpcm;
for (auto val : en) {
int16_t result = ~adpcm.ADPCMDecoder(val & 0xf) + 1;
int8_t temp0 = ((result)&0xff);
int8_t temp1 = ((result)&0xff00) >> 8;
de.push_back(temp0);
de.push_back(temp1);
result = ~adpcm.ADPCMDecoder(val >> 4) + 1;
temp0 = ((result)&0xff);
temp1 = (result & 0xff00) >> 8;
de.push_back(temp0);
de.push_back(temp1);
}
}
int i{0};
for (auto val : de) {
qDebug() << "real:" << data[i] << "decoded: " << val;
i++;
}
}
I'm sure that my class and encode/decode is right ,just after decode I should do somethings to show correct numbers(but I donw know which casting is failed).
why I'm sure? because when I see my output in QDebug , every other sample(after decode) are correct (with few errors, in big datas errors will be smaller than now), but anothers are failed
my output:
real: 26 decoded: 6
real: 29 decoded: 32
real: 33 decoded: 5
real: 36 decoded: 48
real: 40 decoded: 6
real: 44 decoded: 32
real: 48 decoded: 5
real: 52 decoded: 48
real: 56 decoded: 4
real: 60 decoded: 64
data are 8bits in device
Ok , I found my answer
when you have error on any number , your error is in lower bits!
so my predict was on two numbers that was anded to gether , then that number is in lower bits position have much errors!

Difference between C++ openssl/aes and Go crypto/aes

I have two programs on C++ and Go for encrypt data using AES, but they returns different results. Could you explain me the difference? How I can write similar code to get the same result using Go?
C++
g++ aes.cpp -o aes -O3 -lcrypto -std=c++11 && ./aes
#include <iostream>
#include <openssl/aes.h>
using std::cout;
int main(int argc, char const *argv[]) {
uint8_t result[16] = {0};
uint8_t key[32] = {
52, 51, 51, 100, 52, 53, 98, 57, 51, 98, 98, 98, 102, 102, 56, 100,
54, 53, 53, 49, 55, 56, 54, 51, 50, 102, 49, 56, 101, 97, 101, 97,
};
uint8_t data[16] = {
89, 0, 192, 238, 251, 3, 19, 11, 0, 0, 0, 0, 0, 15, 0, 236,
};
AES_KEY ctx;
AES_set_encrypt_key(&key[0], 128, &ctx);
AES_encrypt(data, result, &ctx);
std::cout << "Result: ";
for (auto const& value: result) {
std::cout << unsigned(value) << ",";
}
std::cout << '\n';
return 0;
}
Result: 65,68,199,89,141,129,6,202,211,198,47,54,212,0,243,130
Go
package main
import (
"crypto/aes"
"log"
)
func main() {
result := make([]byte, 16)
key := []byte{
52, 51, 51, 100, 52, 53, 98, 57, 51, 98, 98, 98, 102, 102, 56, 100,
54, 53, 53, 49, 55, 56, 54, 51, 50, 102, 49, 56, 101, 97, 101, 97,
}
data := []byte{89, 0, 192, 238, 251, 3, 19, 11, 0, 0, 0, 0, 0, 15, 0, 236}
cipher, err := aes.NewCipher(key)
if err != nil {
log.Fatal(err)
}
cipher.Encrypt(result, data)
log.Println(result)
}
Result: 18 144 147 200 175 53 202 191 80 17 142 126 228 220 57 180

Finding the minimum value in an array (What's wrong with my code?)

This is for my intro to C++ course. We are currently doing arrays and I'm trying to find the min value for each column of the array. here is what I have:
#include <iostream>
using namespace std;
int main(){
int grade[4][30] = {{76, 70, 80, 90, 100, 83, 61, 63, 64, 65, 97, 69, 70, 79,60, 70, 80, 90, 100, 83, 61, 63, 99, 98, 66, 69, 70, 79},
{74, 70, 80, 90,60, 61, 93, 88, 73, 65, 91, 69, 70, 79, 60, 70, 80, 90, 60, 83, 61, 63, 64, 65, 66, 69, 67, 74},
{72, 70, 80, 90, 99, 84, 62, 63, 99, 65, 66, 69, 70, 79, 60, 70, 80, 90, 99, 83, 61, 63, 64, 65, 66, 69, 70, 77},
{69, 70, 80, 90, 60, 61, 86, 63, 97, 97, 66, 69, 70, 79, 97, 70, 80, 90, 88, 83, 88, 63, 64, 65, 66, 69, 70, 79}};
int a;
for(int x = 0; x < 4; ++x){
a = grade[x][0];
for(int y = 0; y < 30; ++y){
if( a > grade[x][y])
a = grade[x][y];
cout << "a is " << a << " for the " << y << "time" << endl;}
cout << a << endl;}
return 0;
}
My problem is I don't understand why in the last two loops the value turns to 0? The real answer should be 60 for each row.
P.S I used this to find the maximum and it worked, but don't get why it won't work here?
for(int y = 0; y < 30; ++y){
It is because for example your first array contains only 28 explicitly initialized elements and you iterate till 30 (see above). The elements which you didn't initialize yourself are initialized to 0.
Your array initializers have less than 30 numbers. Since your array is declared to take 30 elements, the remaining entries are set to 0.
Since you don't appear to have 0s in your data, you could use 0 as a sentinel to know to stop the loop.

Array of Structs cannot read intergers assigned to them c++

I am trying to assign values to the Arrival, BurstTime, and IOTime arrays. It worked fine when I didn't have Arrival[9]. However trying to pass multiple ints into the variable doesn't work. I get -86638*** numbers. I have been trying to find an answer for days, No luck.
This is my struct.
struct ReadyQueue
{
//static const int MAX_NUMBER = 10;
int ArrivalTime[10];
int BurstTime[10];
int IOTime[10];
std::string Name;
};
and my variables
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
P[1].ArrivalTime[8] = 17, 116, 208, 320, 437, 554, 665, 754 ; // P2
P[2].ArrivalTime[7] = 27, 125, 238, 364, 468, 579, 680; // P3
P[3].ArrivalTime[8] = 45, 155, 276, 392, 515, 642, 739, 820 ; // P4
P[4].ArrivalTime[10] = 62, 186, 343, 489, 603, 715, 807, 887, 952, 997; // P5
P[5].ArrivalTime[7] = 67, 174, 262, 348, 446, 566, 654; // P6
P[6].ArrivalTime[9] = 77, 148, 216, 302, 359, 461, 546, 622, 697; // P7
P[7].ArrivalTime[8] = 83, 196, 306, 409, 499, 608, 702, 773 ; // P8
P[8].ArrivalTime[9] = 92, 192, 296, 386, 492, 599, 692, 734, 803; // P9
P[0].BurstTime[8] = 17 , 18, 17, 16, 14, 16, 14, 15, 15;
P[0].IOTime[8] = 24, 73, 31, 27, 33, 43, 64, 19 ;
P[1].BurstTime[8] = 10, 9, 8, 7, 9, 12, 15, 19 ;
P[1].IOTime[7] = 31, 35, 42, 43, 47, 43, 51 ;
P[2].IOTime[6] = 51, 53, 61, 31, 43, 31 ;
P[2].BurstTime[7] = 18, 23, 24, 22, 21, 20, 12 ;
P[3].BurstTime[8] = 17, 19, 20, 17, 15, 12, 15, 14 ;
P[3].IOTime[7] = 42, 55, 54, 52, 67, 72, 66 ;
P[4].BurstTime[10] = 5, 6, 5, 3, 5, 4, 3, 4, 3, 5 ;
P[4].IOTime[9] = 61, 82, 71, 61, 62, 51, 77, 61, 42 ;
P[5].BurstTime[7] = 10, 12, 14, 11, 15, 13, 11 ;
P[5].IOTime[6] = 35, 41, 33, 32, 41, 29 ;
P[6].BurstTime[7] = 6, 7, 5, 4, 5, 7, 8, 6, 5 ;
P[6].IOTime[8] = 18, 21, 19, 16, 29, 21, 22, 24 ;
P[7].BurstTime[8] = 9, 12, 14, 14, 16, 14, 13, 15 ;
P[7].IOTime[7] = 52, 42, 31, 21, 43, 31, 32 ;
P[8].BurstTime[9] = 6, 4, 6, 6, 7, 4, 5, 5, 4 ;
P[8].BurstTime[8] = 35, 41, 33, 32, 41, 29, 16, 22 ;
Thank you very much
I want to clarify what those assignments do, because I see some wrong answers.
Let's see it with an example:
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
First, that statement is assigning 0 in the eleventh element of the ArrivalTime array and I don't think you wanted to do this due to ArrivalTime[9] is the last element.
Second, the comma operator evaluates the first operand, discard the result, and then evaluates the second operand and returns his value. In the example you could think this evaluation returns 788, but assign operator have more precedence than comma, so, the statement will evaluate like this:
((P[0].ArrivalTime[10] = 0), 98, 221, 327, 423, 530, 628, 719, 788 ;
Change this:
struct ReadyQueue
{
//static const int MAX_NUMBER = 10;
int ArrivalTime[10];
int BurstTime[10];
int IOTime[10];
std::string Name;
};
to this:
struct Item
{
int ArrivalTime;
int BurstTime;
int IOTime;
};
struct Ready_queue
{
string name;
queue<Item> items;
};
where queue is std::queue.
If that doesn't suit your higher level purpose, then something similar that does suit that (unexplained) purpose.
The main point is an inversion of the logical structure, putting related data together.
Do note that e.g. x = 6, 4, 6, 6, 7, 4, 5, 5, 4 ; is parsed as (x = 6), 4, 6, 6, 7, 4, 5, 5, 4 ; and thus is equivalent to just = 6;. The longwinded expression after the assignment is using the comma operator, which evaluates the expressions in ordinary reading order, producing the value of the last one. Due to the parsing also that final value is discarded.
Please note that my answer contained a mistake which I corrected it: equal operator has a higher priority than the comma operator (it might still contain traces of it)
This is not how you assign an array to a variable.
what you are doing is simply:
assign 788 0 to p[0].ArrivalTime[10] //the 11th element of p[0] which is outside the reserved space for the array
because the comma operator what it does is that it evaluates every one from left to right and return the last value: example:
int i=0,j;
j=i++,(i+=5),i; //j=0 and i=6 //because it is in fact (j=i++),(i+=5),i;
j=(i++,(i+=5),i); //j=6 and i=6
what you are trying to do is assign p[0].arrivalTime to an array of 10. You should do it this way:
P[0].ArrivalTime[0] = 0 ;
P[0].ArrivalTime[1] = 98 ;
...
P[0].ArrivalTime[9] = 788 ;
I don't know any method that assign an array to an array variable after declaration
You cannot do assignments to arrays like this in c/c++. You can use a similar syntax with {} for initializing arrays, but it won't work for what you want to do here. You could use memcpy to copy the arrays into the memory locations in the struct.
memcpy( p[0].ArrivalTime,
(const int[9]) {0, 98, 221, 327, 423, 530, 628, 719, 788},
sizeof(int [9])
);
Note that the comma is an operator which evaluates a list of expressions and returns the value of the last expression. This means that
P[0].ArrivalTime[10] = 0, 98, 221, 327, 423, 530, 628, 719, 788 ;
assigns 0 to the value at index 10 of the array named ArrivalTime and ignores the rest of the list.