I have two arrays:
unsigned char channeltab1[7][12]; //array which I receive from socket(Array is the same as below)
unsigned char equal_channeltab1[7][12] //arrays which I wants to compare with channeltab1
{
{0x10, 0x0f, 0x02, 0x02, 0x01, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x02, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x03, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x04, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x05, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x06, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
{0x10, 0x0f, 0x02, 0x02, 0x07, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef},
};
I want compare this arrays, but function strcmp work only with one-dimensional arrays.
I try use strncmp:
for(int x = 0; x<7; x++)
{
for(int i =1; x<12;i++)
{
if (strncmp (reinterpret_cast<const char*>(channeltab1[x][i]),reinterpret_cast<const char*>(equal_channeltab1[x][i]),2) == 0)
{
/*...*/
}
else
{
/*...*/
}
}
}
But when application run this instruction says:
Memory fault
If i use:
for(int x = 0; x<7; x++)
{
if (strncmp (reinterpret_cast<const char*>(channeltab1[x]),reinterpret_cast<const char*>(equal_channeltab1[x]),2) == 0)
{
/*..*/
}
else
{
/*..*/
}
}
They are not the same for program.
What should I do?
Following may help:
bool is_equal(const unsigned char (&lhs)[7][12], const unsigned char (&rhs)[7][12])
{
for (int i = 0; i != 7; ++i) {
if (memcmp(lhs[i], rhs[i], 12) != 0) {
return false;
}
}
return true;
}
or even (thanks to Hanno Binder)
bool is_equal(const unsigned char (&lhs)[7][12], const unsigned char (&rhs)[7][12])
{
return memcmp(lhs, rhs, sizeof(lhs)) != 0;
}
You can simply use memcmp
(sizeof(channeltab1) == sizeof(equal_channeltab1)
&& (memcmp(channeltab1, equal_channeltab1, sizeof(equal_channeltab1)) == 0)
Note you have to make sure theirs sizes are equal.
I would suggest you to implement a new comparing function rather then trying to use these C functions. You can start from something like this:
bool checkEquals(unsigned char** a, unsigned char** b, size_t outterSize, size_t innerSize)
{
for (size_t i = 0; i < outterSize; ++i)
{
for (size_t j = 0; j < innerSize; ++j)
{
if (a[i][j] != b[i][j])
{
return false;
}
}
}
return true;
}
"strncmp" is used for standard "C" strings comparsion (or ASCII ones) not for data as it's in your case (data and arrays are always the same in "C++" language). So you should use 'memcpy' instead. So your code will look something like this:
for(int x = 0; x<7; x++)
{
if (memcmp((void*)channeltab1[x],(void*)equal_channeltab1[x], 12 * sizeof(unsigned char)) == 0)
{
/*equal*/
}
else
{
/*not equal*/
}
}
Use std::Array
std::array<unsigned char, 7*12> channeltab1;
std::array<unsigned char, 7*12> equal_channeltab1 = {
0x10, 0x0f, 0x02, 0x02, 0x01, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x02, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x03, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x04, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x05, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x06, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef,
0x10, 0x0f, 0x02, 0x02, 0x07, 0x00, 0x00, 0x06, 0x10, 0x0e, 0xff, 0xef
};
and to compare, you can now do:
if (channeltab1 == equal_channeltab1){
//do stuff
}
note, an array[x*y] is the same as an array[x][y]
Multidimensional arrays are store in continuous memory so actually memcmp should work, memcmp avoids mistakes in the cast.
memcmp(channeltab1, equal_channeltab1, sizeof(channeltab1))
Edit: strncmp doesn't work because there could be zero's in the values.
Related
Below is a sketch inspired from an example, that I stripped down to the very bare minimum to fit my needs :
#include <Crypto.h>
#include <AES.h>
#include <string.h>
struct TestVector
{
const char *name;
byte key[32];
byte plaintext[16];
byte ciphertext[16];
};
// Define the ECB test vectors from the FIPS specification.
static TestVector const testVectorAES128 = {
.name = "AES-128-ECB",
.key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
.plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
.ciphertext = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A}
};
AES128 aes128;
byte buffer[16];
void testCipher(BlockCipher *cipher, const struct TestVector *test)
{
crypto_feed_watchdog();
Serial.print(test->name);
Serial.print(" Encryption ... ");
cipher->setKey(test->key, cipher->keySize());
cipher->encryptBlock(buffer, test->plaintext);
if (memcmp(buffer, test->ciphertext, 16) == 0)
Serial.println("Passed");
else
Serial.println("Failed");
Serial.print(test->name);
Serial.print(" Decryption ... ");
cipher->decryptBlock(buffer, test->ciphertext);
if (memcmp(buffer, test->plaintext, 16) == 0)
Serial.println("Passed");
else
Serial.println("Failed");
}
void setup()
{
Serial.begin(9600);
delay(3000);
Serial.println();
Serial.println(sizeof(AES128));
Serial.println();
testCipher(&aes128, &testVectorAES128);
Serial.println();
}
void loop()
{
}
It works.
I would like to modify this so that I end up with 2 functions : encrypt() and decrypt() which would both take a char array as a parameter.
The sketch above has .plaintext and .ciphertext hardcoded as a constant array of hex values/bytes (I guess?). How do I make these "dynamic"/variable, in order to feed encrypt() and decrypt()?
I am not comfortable with c++.
My project is to have this script feed a var like char hushhush[123] = "s0m3 3ncrypt3d stuff", then I would send the content of hushhush to a webserver/API running PHP, and decrypt with openssl_decrypt() (https://www.php.net/manual/en/function.openssl-decrypt.php)
My second problem will be: openssl_decrypt() needs the key to be of type string $passphrase. What is the "string" of 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F ?
For example, I'm using 320x200x256 graphics (VGA)
unsigned char g_320x200x256[] =
{
/* MISC */
0x63,
/* SEQ */
0x03, 0x01, 0x0F, 0x00, 0x0E,
/* CRTC */
0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
0xFF,
/* GC */
0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
0xFF,
/* AC */
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x41, 0x00, 0x0F, 0x00, 0x00
};
WriteRegisters(g_320x200x256);
So, how can I use graphics with another size and 16M color??
Help me, please. :((
EDIT
This is WriteRegister function
void VideoGraphicsArray::WriteRegisters(uint8_t* registers)
{
// misc
miscPort.Write(*(registers++));
// sequencer
for(uint8_t i = 0; i < 5; i++)
{
sequencerIndexPort.Write(i);
sequencerDataPort.Write(*(registers++));
}
// cathode ray tube controller
crtcIndexPort.Write(0x03);
crtcDataPort.Write(crtcDataPort.Read() | 0x80);
crtcIndexPort.Write(0x11);
crtcDataPort.Write(crtcDataPort.Read() & ~0x80);
registers[0x03] = registers[0x03] | 0x80;
registers[0x11] = registers[0x11] & ~0x80;
for(uint8_t i = 0; i < 25; i++)
{
crtcIndexPort.Write(i);
crtcDataPort.Write(*(registers++));
}
// graphics controller
for(uint8_t i = 0; i < 9; i++)
{
graphicsControllerIndexPort.Write(i);
graphicsControllerDataPort.Write(*(registers++));
}
// attribute controller
for(uint8_t i = 0; i < 21; i++)
{
attributeControllerResetPort.Read();
attributeControllerIndexPort.Write(i);
attributeControllerWritePort.Write(*(registers++));
}
attributeControllerResetPort.Read();
attributeControllerIndexPort.Write(0x20);
}
The code you are using is a dump of values for the VGA configuration registers. The fastest clock generator VGA has to offer runs at about 28 MHz. So you can't output 1920x1080x60 = 124 416 000 pixels per second but only about 28 000 000 pixels per second. That is why you won't find the desired values for the configuration registers.
I try to geneate CRC4 lookup tables in C++ for the known CRC algorithms CRC-4/INTERLAKEN and CRC-4/ITU. The CRC definitions are as follows:
width=4 poly=0x3 init=0xf refin=false refout=false xorout=0xf check=0xb residue=0x2 name="CRC-4/INTERLAKEN"
width=4 poly=0x3 init=0x0 refin=true refout=true xorout=0x0 check=0x7 residue=0x0 name="CRC-4/G-704"
I've started adapting the code found from the answer here to generate lookup table to compare with tables found in the answer found here. If the bit order does not matter for this code, besides polynomial which is the same what else I need to consider? How different would the codes for INTERLAKEN and ITU algorithms be?
The code:
#include <iomanip>
#include <iostream>
void make_crc_table(unsigned long crcTable[])
{
unsigned long POLYNOMIAL = 0x3;
unsigned long remainder;
unsigned char b = 0;
do
{
remainder = b;
for (unsigned long bit = 8; bit > 0; --bit)
{
if (remainder & 1)
remainder = (remainder >> 1) ^ POLYNOMIAL;
else
remainder = (remainder >> 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
int main()
{
unsigned long crcTable[256];
make_crc_table(crcTable);
// Print the CRC table
for (size_t i = 0; i < 256; i++)
{
std::cout << "0x";
std::cout << std::setfill('0') << std::setw(2) << std::hex << crcTable[i];
if (i % 16 == 15)
std::cout << "," << std::endl;
else
std::cout << ", ";
}
return 0;
}
The output:
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01, 0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03,
0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02, 0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00,
0x00, 0x02, 0x03, 0x01, 0x01, 0x03, 0x02, 0x00, 0x02, 0x00, 0x01, 0x03, 0x03, 0x01, 0x00, 0x02,
0x03, 0x01, 0x00, 0x02, 0x02, 0x00, 0x01, 0x03, 0x01, 0x03, 0x02, 0x00, 0x00, 0x02, 0x03, 0x01,
Original question ends here.
Update after rcgldr's answer:
#include <iostream>
#include <bitset>
#include <iomanip>
void make_crc_table(unsigned int crcTable[])
{
unsigned char POLYNOMIAL = 0xc;
unsigned char remainder;
unsigned char b = 0;
do
{
remainder = b;
for (int bit = 8; bit > 0; --bit)
{
if (remainder & 0x80)
remainder = (remainder << 1) ^ POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
int main()
{
unsigned int crcTable[256];
make_crc_table(crcTable);
for (size_t i = 0; i < 256; i++)
{
std::cout << "0x";
std::cout << std::setfill('0') << std::setw(2) << std::hex << (crcTable[i]);
if (i % 16 == 15)
std::cout << "," << std::endl;
else
std::cout << ", ";
}
return 0;
}
Output of the code:
0x00, 0x0c, 0x18, 0x14, 0x30, 0x3c, 0x28, 0x24, 0x60, 0x6c, 0x78, 0x74, 0x50, 0x5c, 0x48, 0x44,
0xc0, 0xcc, 0xd8, 0xd4, 0xf0, 0xfc, 0xe8, 0xe4, 0xa0, 0xac, 0xb8, 0xb4, 0x90, 0x9c, 0x88, 0x84,
0x8c, 0x80, 0x94, 0x98, 0xbc, 0xb0, 0xa4, 0xa8, 0xec, 0xe0, 0xf4, 0xf8, 0xdc, 0xd0, 0xc4, 0xc8,
0x4c, 0x40, 0x54, 0x58, 0x7c, 0x70, 0x64, 0x68, 0x2c, 0x20, 0x34, 0x38, 0x1c, 0x10, 0x04, 0x08,
0x14, 0x18, 0x0c, 0x00, 0x24, 0x28, 0x3c, 0x30, 0x74, 0x78, 0x6c, 0x60, 0x44, 0x48, 0x5c, 0x50,
0xd4, 0xd8, 0xcc, 0xc0, 0xe4, 0xe8, 0xfc, 0xf0, 0xb4, 0xb8, 0xac, 0xa0, 0x84, 0x88, 0x9c, 0x90,
0x98, 0x94, 0x80, 0x8c, 0xa8, 0xa4, 0xb0, 0xbc, 0xf8, 0xf4, 0xe0, 0xec, 0xc8, 0xc4, 0xd0, 0xdc,
0x58, 0x54, 0x40, 0x4c, 0x68, 0x64, 0x70, 0x7c, 0x38, 0x34, 0x20, 0x2c, 0x08, 0x04, 0x10, 0x1c,
0x28, 0x24, 0x30, 0x3c, 0x18, 0x14, 0x00, 0x0c, 0x48, 0x44, 0x50, 0x5c, 0x78, 0x74, 0x60, 0x6c,
0xe8, 0xe4, 0xf0, 0xfc, 0xd8, 0xd4, 0xc0, 0xcc, 0x88, 0x84, 0x90, 0x9c, 0xb8, 0xb4, 0xa0, 0xac,
0xa4, 0xa8, 0xbc, 0xb0, 0x94, 0x98, 0x8c, 0x80, 0xc4, 0xc8, 0xdc, 0xd0, 0xf4, 0xf8, 0xec, 0xe0,
0x64, 0x68, 0x7c, 0x70, 0x54, 0x58, 0x4c, 0x40, 0x04, 0x08, 0x1c, 0x10, 0x34, 0x38, 0x2c, 0x20,
0x3c, 0x30, 0x24, 0x28, 0x0c, 0x00, 0x14, 0x18, 0x5c, 0x50, 0x44, 0x48, 0x6c, 0x60, 0x74, 0x78,
0xfc, 0xf0, 0xe4, 0xe8, 0xcc, 0xc0, 0xd4, 0xd8, 0x9c, 0x90, 0x84, 0x88, 0xac, 0xa0, 0xb4, 0xb8,
0xb0, 0xbc, 0xa8, 0xa4, 0x80, 0x8c, 0x98, 0x94, 0xd0, 0xdc, 0xc8, 0xc4, 0xe0, 0xec, 0xf8, 0xf4,
0x70, 0x7c, 0x68, 0x64, 0x40, 0x4c, 0x58, 0x54, 0x10, 0x1c, 0x08, 0x04, 0x20, 0x2c, 0x38, 0x34,
The bit order matters. The question's code is using reflected input and output. That means the polynomial should be bit reversed from 0x03 to 0x0c. To confirm this, table entry [0x80] should be 0x0c.
For the Interlaken table, the code should look like:
void make_crc_table(unsigned char crcTable[])
{
unsigned char POLYNOMIAL = 0x30;
unsigned char remainder;
unsigned char b = 0;
do
{
remainder = b;
for (int bit = 8; bit > 0; --bit)
{
if (remainder & 0x80)
remainder = (remainder << 1) ^ POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[(size_t)b] = remainder;
} while (0 != ++b);
}
Note that the CRC will be in the upper 4 bits of a byte. When done, the code will need to return (crc>>4)^0x0f.
As Hardware, I'm using an Arduino Due and a GPS Receiver from u-Blox (https://www.sparkfun.com/products/15005) for my project. I basically want to retrieve a certain message (UBX-RXM-RAWX) via UART. As I will parse this message in post-processing, it would be fine to just read all binary data and store it directly onto an SD card. Unfortunately, not being very experienced in C++, I'm having troubles storing binary data into any file.
I see I'm missing some general knowledge there, and so I wanted to ask if you could help me out? My code is attached as well or can be found on github: https://github.com/dariopa/GPS-Logging-Station/blob/master/GPS%20Station/_UBX_GPS_StoreBinaryMessage_RAWX_DUE/_UBX_GPS_StoreBinaryMessage_RAWX_DUE.ino
Thanks for any help!
// RETRIEVE RAWX MESSAGE FOR RINEX GENERATION.
// Microcontroller: Arduino DUE
// GPS Receiver: NEO-M8P-2 (https://www.sparkfun.com/products/15005)
#include <SD.h>
File binaryFile;
const int CS = 10; // ChipSelect
const char UBLOX_INIT[] PROGMEM = {
// Disable NMEA
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x24, // GxGGA off
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2B, // GxGLL off
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, // GxGSA off
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x39, // GxGSV off
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x40, // GxRMC off
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0xF0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x05, 0x47, // GxVTG off
// Disable UBX
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x46, // RXM-RAWX off
// Enable UBX
0xB5, 0x62, 0x06, 0x01, 0x08, 0x00, 0x02, 0x15, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4B, // RXM-RAWX on
// Rate
0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xE8, 0x03, 0x01, 0x00, 0x01, 0x00, 0x01, 0x39, //(1Hz)
// 0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xD0, 0x07, 0x01, 0x00, 0x01, 0x00, 0xED, 0xBD, // (0.5Hz)
// 0xB5, 0x62, 0x06, 0x08, 0x06, 0x00, 0xB8, 0x0B, 0x01, 0x00, 0x01, 0x00, 0xD9, 0x41, // (0.33Hz)
};
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
delay(3000);
// send configuration data in UBX protocol
for (int i = 0; i < sizeof(UBLOX_INIT); i++) {
Serial1.write( pgm_read_byte(UBLOX_INIT + i) );
Serial.write( pgm_read_byte(UBLOX_INIT + i) );
delay(10); // simulating a 38400baud pace (or less), otherwise commands are not accepted by the device.
}
// SD CARD
// Initialize SD Card
pinMode(CS, OUTPUT);
if (!SD.begin(CS)) {
Serial.println("Initialization of SD card failed - Freeze!");
while (1) {}
}
else {
Serial.println("Initialization done.");
}
}
void loop() {
if (Serial1.available()) {
// read from port serial, send to port Serial:
char Coord[300] = {Serial1.read()};
Serial.write(Coord);
binaryFile = SD.open("Data.bin", FILE_WRITE);
if (binaryFile) {
binaryFile.println(Coord);
}
}
}
char Coord[300] = {Serial1.read()};
This initialized Coord[0] to the return of Serial1.read(). The rest of 299 member of Coord array are initialized with zero.
If Serial1.read() returns an integer int. If it's -1 than read was not succcessfull. Otherwise it's one valid character.
You want to read one character at a time and store it:
void setup() {
...
// is there a point in opening the binaryFile each loop!?
binaryFile = SD.open("Data.bin", FILE_WRITE);
if (!binaryFile) {
// handle errror
assert(0);
}
}
void loop() {
if (Serial1.available()) {
int ci = Serial1.read();
if (ci == -1) {
// handle errpr
return;
}
char c = ci;
Serial.write(c);
binaryFile.write(c);
}
}
#pragma once
#include <string>
#include <vector>
#include <stdint.h>
class PasswordCrypt
{
public:
PasswordCrypt(std::vector<uint8_t> buffer);
~PasswordCrypt(void);
void PassCrypto(std::vector<uint8_t> buffer);
const std::vector<uint8_t>& Encrypt(const std::vector<uint8_t>& buffer);
const std::vector<uint8_t>& Decrypt(std::vector<uint8_t>& buffer);
private:
uint8_t* key;
};
--------------------------------------------------------------------------------------
#include "PasswordCrypt.h"
PasswordCrypt::PasswordCrypt(std::vector<uint8_t> buffer)
{
this->key = new uint8_t[200];
int sum = 0;
for (int i = 0 ; i< buffer.size() ;i++)
sum += buffer[i];
srand(sum);
uint8_t hash[0x10];
for (int i = 0; i < 0x10; i++)
hash[i] =(uint8_t)rand();
for (int i = 1; i < 0x100; i++)
{
key[i * 2] = (uint8_t)i;
key[(i * 2) + 1] = (uint8_t)(i ^ hash[i & 0x0F]);
}
for (int i = 1; i < 0x100; i++)
for (int j = 1 + i; j < 0x100; j++)
if (key[(i * 2) + 1] < key[(j * 2) + 1])
{
key[i * 2] ^= key[j * 2];
key[j * 2] ^= key[i * 2];
key[i * 2] ^= key[j * 2];
key[(i * 2) + 1] ^= key[(j * 2) + 1];
key[(j * 2) + 1] ^= key[(i * 2) + 1];
key[(i * 2) + 1] ^= key[(j * 2) + 1];
}
}
PasswordCrypt::~PasswordCrypt(void)
{
delete[] this->key;
}
const uint8_t scanCodeToVirtualKeyMap[] =
{
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xBD, 0xBB, 0x08, 0x09,
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0xDB, 0xDD, 0x0D, 0x11, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0xBA, 0xC0, 0xDF, 0x10, 0xDE, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0xBC, 0xBE, 0xBF, 0x10, 0x6A, 0x12, 0x20, 0x14, 0x70, 0x71, 0x72, 0x73, 0x74,
0x75, 0x76, 0x77, 0x78, 0x79, 0x90, 0x91, 0x24, 0x26, 0x21, 0x6D, 0x25, 0x0C, 0x27, 0x6B, 0x23,
0x28, 0x22, 0x2D, 0x2E, 0x2C, 0x00, 0xDC, 0x7A, 0x7B, 0x0C, 0xEE, 0xF1, 0xEA, 0xF9, 0xF5, 0xF3,
0x00, 0x00, 0xFB, 0x2F, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xED,
0x00, 0xE9, 0x00, 0xC1, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x09, 0x00, 0xC2, 0x00,
};
const uint8_t virtualKeyToScanCodeMap[] =
{
0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x00, 0x00, 0x4C, 0x1C, 0x00, 0x00,
0x2A, 0x1D, 0x38, 0x00, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x39, 0x49, 0x51, 0x4F, 0x47, 0x4B, 0x48, 0x4D, 0x50, 0x00, 0x00, 0x00, 0x54, 0x52, 0x53, 0x63,
0x0B, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, 0x32, 0x31, 0x18,
0x19, 0x10, 0x13, 0x1F, 0x14, 0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C, 0x5B, 0x5C, 0x5D, 0x00, 0x5F,
0x52, 0x4F, 0x50, 0x51, 0x4B, 0x4C, 0x4D, 0x47, 0x48, 0x49, 0x37, 0x4E, 0x00, 0x4A, 0x53, 0x35,
0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x57, 0x58, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x45, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x2A, 0x36, 0x1D, 0x1D, 0x38, 0x38, 0x6A, 0x69, 0x67, 0x68, 0x65, 0x66, 0x32, 0x20, 0x2E, 0x30,
0x19, 0x10, 0x24, 0x22, 0x6C, 0x6D, 0x6B, 0x21, 0x00, 0x00, 0x27, 0x0D, 0x33, 0x0C, 0x34, 0x35,
0x28, 0x73, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x56, 0x1B, 0x2B, 0x29,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x5C, 0x7B, 0x00, 0x6F, 0x5A, 0x00,
0x00, 0x5B, 0x00, 0x5F, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00
};
const std::vector<uint8_t>& PasswordCrypt::Encrypt(const std::vector<uint8_t>& buffer)
{
std::vector<uint8_t> result(buffer.size());
for (int i = 0; i < buffer.size(); i++)
{
bool upper = false;
if (buffer[i] == 0) break;
else
{
uint8_t b =this->key[buffer[i] * 2];
if (b > 0x80)
{
b = (uint8_t)(this->key[buffer[i] * 2] - 0x80);
upper = true;
}
result[i] += scanCodeToVirtualKeyMap[b];
}
if (!upper && result[i] >= 'A' && result[i] <= 'Z') result[i] += 'a' - 'A';
}
return result;
}
const std::vector<uint8_t>& PasswordCrypt::Decrypt(std::vector<uint8_t>& buffer)
{
std::vector<uint8_t> result(buffer.size(), 0);
for (int j = 0; j < buffer.size(); j++)
{
uint8_t c = buffer[j];
if (buffer[j] >= 'a' && buffer[j] <= 'z')
buffer[j] -= 'a' - 'A';
uint8_t d = virtualKeyToScanCodeMap[buffer[j]];
if (c >= 'A' && c <= 'Z')
d += 0x80;
for (uint8_t i = 0; i <= 255; i++)
{
uint8_t b = (uint8_t)this->key[i * 2];
if (b == d)
{
result[j] = i;
break;
}
}
}
return result;
}
---------------------------------------------------------------------------------------
#include <iostream>
#include <Windows.h>
#include <string>
#include <stdint.h>
#include "PasswordCrypt.h"
#include <iomanip>
using namespace std;
void output_hex(std::ostream& out, std::vector<uint8_t>& data) {
for (std::vector<uint8_t>::iterator i=data.begin();i<data.end();i++)
out << std::hex
<< std::setw(2)
<< std::setfill('0')
<< static_cast<int>(data[*i])
<< " ";
out << endl;
}
int main()
{
std::string test="Hellow World!";
std::vector<uint8_t> buf(test.begin(), test.end());
PasswordCrypt dec(buf);
//output_hex(cout, buf);
std::vector<uint8_t> enced = dec.Encrypt(buf);
//output_hex(cout, enced);
std::vector<uint8_t> deced = dec.Decrypt(enced);
//output_hex(cout, deced);
system("pause");
return 0;
}
Error:
Windows has triggered a breakpoint in
testcrypto.exe.
This may be due to a corruption of the
heap, which indicates a bug in
testcrypto.exe or any of the DLLs it
has loaded.
This may also be due to the user
pressing F12 while testcrypto.exe has
focus.
You have a classic buffer overrun. Here you allocate 200 bytes for key:
this->key = new uint8_t[200];
Here, however:
for (int i = 1; i < 0x100; i++)
{
key[i * 2] = (uint8_t)i;
You (attempt to) write to k[2] through key[2 * 0x100]. 2 * 0x100 is 0x200, which is 512 in decimal. It would appear that where you allocate the buffer, you should really allocate 0x200 elements.
Some of the other code looks like it tries to access key[0x200] -- to make that work, you'd want/need to allocate 0x201 elements (0x200 elements will run from key[0] through key[0x1ff] inclusive).
Edit: doing a bit more looking, it gets even worse. Perhaps putting these three lines next to each other will make the next problem more obvious:
const std::vector<uint8_t>& PasswordCrypt::Encrypt(const std::vector<uint8_t>& buffer)
{
std::vector<uint8_t> result(buffer.size());
[ ...]
return result;
You're returning a reference to a local variable, so the caller receives a dangling reference.
j < 0x100;
0x100 is not the same as 100. It's 256. And your key array is only 200 elements long.
You then go off and try to access key[j * 2], which is way off the end of the array, trampling all over random bits of memory. That's your problem.
Your other problem is using xor-swapping instead of something more readable - while you might think it's a "neat trick", it really isn't. It makes things much less legible and doesn't provide any meaningful performance benefit.