Streaming in a char Number - c++

Is there a way to stream in a number to a unsigned char?
istringstream bytes( "13 14 15 16 17 18 19 20" );
unsigned char myChars[8];
for( int i = 0; i < 8 && !bytes.eof(); i++ )
{
bytes >> myChars[i];
cout << unsigned( myChars[i] ) << endl;
}
This code currently outputs the ascii values of the first 8 non-space characters:
49 51 49 52 49 53 49 54
But what I want is the numerical values of each token:
13
14
15
16
17
18
19
20

You are reading a char at a time, which means you get '1', '3', skips the space, '1', '4', skips the space, etc.
To read the values as NUMBERS, you need to use an integer type as a temporary:
unsigned short s;
bytes >> s;
myChars[i] = s;
Now, the stream will read an integer value, e.g. 13, 14, and store it in s. Then you convert it to a unsigned char with myChars[i] = s;.

So there is a lot of error checking that you'll bypass to do this without a temporary. For example, does each number being assigned fit in a byte and are there more numbers in bytes than elements of myChars? But presuming you've already delt with those you can just use an istream_iterator<unsigned short>:
copy(istream_iterator<unsigned short>{ bytes }, istream_iterator<unsigned short>{}, begin(myChars))
Live Example
An additional note here: A char[] typically contains a null terminated string. Presuming that's not what you intend, it would be gracious of you to indicate to the reader that's not how you're using it. In c++11 you were given int8_t/uint8_t to do just that. Using something like: uint8_t myChars[8] would make your code more readable.

Related

2nd Variation on Caesar Cipher (Having problems with splitting final string into parts)

Prompt:
In this country soldiers are poor but they need a certain level of secrecy for their communications so, though they do not know Caesar cypher, they reinvent it in the following way.
They use ASCII, without really knowing it, but code only letters a-z and A-Z. Other characters are kept such as.
They change the "rotate" each new message. This "rotate" is a prefix for their message once the message is coded. The prefix is built of 2 letters, the second one being shifted from the first one by the "rotate", the first one is the first letter, after being downcased, of the uncoded message.
For example if the "rotate" is 2, if the first letter of the uncoded message is 'J' the prefix should be 'jl'.
To lessen risk they cut the coded message and the prefix in five pieces since they have only five runners and each runner has only one piece.
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter. If there are many options of how to split, choose the option where the fifth part has the longest length, provided that the previous conditions are fulfilled. If the last part is the empty string don't put this empty string in the resulting array.
For example, if the coded message has a length of 17 the five parts will have lengths of 4, 4, 4, 4, 1. The parts 1, 2, 3, 4 are evenly split and the last part of length 1 is shorter. If the length is 16 the parts will be of lengths 4, 4, 4, 4, 0. Parts 1, 2, 3, 4 are evenly split and the fifth runner will stay at home since his part is the empty string and is not kept.
Could you ease them in programming their coding?
Example with shift = 1 :
message : "I should have known that you would have a perfect answer for me!!!"
code : => ["ijJ tipvme ibw", "f lopxo uibu z", "pv xpvme ibwf ", "b qfsgfdu botx", "fs gps nf!!!"]
By the way, maybe could you give them a hand to decode?
//Ends here
Issues faced:
Can't figure out how to divide the encoded string according to the given conditions. I understand the math behind how the division needs to be done, but can't convert it into code. I know that the num variable that I used needs to be decremented by 4 and the count variable should be incremented by 4 till the condition (num/4 > count) because the condition is such that if the string can be split in multiple ways, then we should do it such that the 5th part is of the longest length.
My code:
static vector<string> encodeStr(const string &s, int shift)
{
char pre = tolower(s[0]);
pre += shift;
string newS = "";
newS += tolower(s[0]);
newS += pre;
vector<string> ans;
for (int i = 0; i < (int)s.size(); i++)
{
if ((s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122))
{
char c = s[i];
c += shift;
newS += c;
}
else
newS.push_back(s[i]);
}
if (newS.size() % 4 == 0)
{
int parts = newS.size() / 4;
int start = 0;
while (start < (int)newS.size())
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
}
else if (newS.size() % 5 == 0)
{
int parts = newS.size() / 5;
int start = 0;
while (start < (int)newS.length())
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
}
else if (newS.length() % 5 != 0 && newS.length() % 4 != 0)
{
int num = newS.length();
int count = 0;
int start = 0;
while (num % 4 != 0)
{
num--;
count++;
}
while (num / 4 > count)
{
num = num - 4;
count = count + 4;
}
int x = newS.length() - count;
int parts = x / 4;
while (start < (int)newS.length() - count)
{
ans.push_back(newS.substr(start, parts));
start += parts;
}
ans.push_back(newS.substr((int)newS.size() - count, count));
}
return ans;
}
static string decode(vector<string> &s)
{
string s1 = "";
char check = ' ' - 1;
for (int i = 0; i < (int)s.size(); i++)
{
s1 += s[i];
}
char a = s1[1];
char b = s1[0];
int shift = a - b;
s1.erase(0, 2);
transform(s1.begin(), s1.end(), s1.begin(), [&](auto x)
{
if ((x >= 65 && x <= 90) || (x >= 97 && x <= 122))
return x -= shift;
else
return x;
});
for (int i = 0; i < (int)s1.size(); i++)
{
if (s1[i] == check)
{
s1[i]++;
}
}
return s1;
}
Code Output
First, we need to extract the important requirements from the story-text. An evaluation of the text leads to:
Caesar cypher
Based on ASCII
only upper and lowercase alpha letters shall be encoded ('A'-'Z', 'a'-'z')
The key (shift-information) shall be encoded and transmitted by along the message as 2 letter prefix. Taking the first letter of the text, unencrypted, as part 1 of the encrypted key and shifting this letter by the key and transmit it as part 2.
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter.
The 2-letter encrypted key shall be a prefix for parts of the split message.
For the following design, we can derive 3 major blocks:
We need a Caesar Cypher encryption/decryption algorithm
The key encryption/decryption must be implemented
The original message must be split according to requirements.
Let us start with the design for the Caesar Cypher encryption/decryption algorithm. We will take advantage of the ASCII code, where all characters have a defined associated numerical value. Please see the table below for the printable characters:
Hex Dec Bin Hex Dec Bin Hex Dec Bin
20 32 00100000 # 40 64 01000000 ` 60 96 01100000
! 21 33 00100001 A 41 65 01000001 a 61 97 01100001
" 22 34 00100010 B 42 66 01000010 b 62 98 01100010
# 23 35 00100011 C 43 67 01000011 c 63 99 01100011
$ 24 36 00100100 D 44 68 01000100 d 64 100 01100100
% 25 37 00100101 E 45 69 01000101 e 65 101 01100101
& 26 38 00100110 F 46 70 01000110 f 66 102 01100110
' 27 39 00100111 G 47 71 01000111 g 67 103 01100111
( 28 40 00101000 H 48 72 01001000 h 68 104 01101000
) 29 41 00101001 I 49 73 01001001 i 69 105 01101001
* 2a 42 00101010 J 4a 74 01001010 j 6a 106 01101010
+ 2b 43 00101011 K 4b 75 01001011 k 6b 107 01101011
, 2c 44 00101100 L 4c 76 01001100 l 6c 108 01101100
- 2d 45 00101101 M 4d 77 01001101 m 6d 109 01101101
. 2e 46 00101110 N 4e 78 01001110 n 6e 110 01101110
/ 2f 47 00101111 O 4f 79 01001111 o 6f 111 01101111
0 30 48 00110000 P 50 80 01010000 p 70 112 01110000
1 31 49 00110001 Q 51 81 01010001 q 71 113 01110001
2 32 50 00110010 R 52 82 01010010 r 72 114 01110010
3 33 51 00110011 S 53 83 01010011 s 73 115 01110011
4 34 52 00110100 T 54 84 01010100 t 74 116 01110100
5 35 53 00110101 U 55 85 01010101 u 75 117 01110101
6 36 54 00110110 V 56 86 01010110 v 76 118 01110110
7 37 55 00110111 W 57 87 01010111 w 77 119 01110111
8 38 56 00111000 X 58 88 01011000 x 78 120 01111000
9 39 57 00111001 Y 59 89 01011001 y 79 121 01111001
: 3a 58 00111010 Z 5a 90 01011010 z 7a 122 01111010
; 3b 59 00111011 [ 5b 91 01011011 { 7b 123 01111011
< 3c 60 00111100 \ 5c 92 01011100 | 7c 124 01111100
= 3d 61 00111101 ] 5d 93 01011101 } 7d 125 01111101
> 3e 62 00111110 ^ 5e 94 01011110 ~ 7e 126 01111110
? 3f 63 00111111 _ 5f 95 01011111 Del 7f 127 01111111
We observe that upper- and lowercase numbers only differ in one bit, which is equal to a distance of 32. We will use this property later.
Then, now, let us come to the core algorithm. Shifting letters.
The biggest problems are potential overflows. So, we need to deal with that.
Then we need to understand what encryption and decryption means. If encryption will shift everthing one to the right, decryption will shift it back to left again.
So, with "def" and key=1, the encrpyted string will be "efg".
And decrpytion with key=1, will shift it to left again. Result: "def"
We can observe that, for decryption, we simply need to shift by -1, so the negative of the key.
Important result: Encryption and decryption can be done with the same routine. We just need to invert the keys.
Let us look now at the overflow problematic. For the moment we will start with uppercase characters only. Characters have an associated code as shown in above ASCII table. For example, the letter 'A' is encoded with 65, 'B' with 66 and so on. Because we do not want to calculate with such big numbers, we normalize them. We simply subtract 'A' from each character. Then
'A' - 'A' = 0
'B' - 'A' = 1
'C' - 'A' = 2
'D' - 'A' = 3
You see the pattern. If we want to encrypt now the letter 'C' with key 3, we can do the following.
'C' - 'A' + 3 = 5 Then we add again 'A' to get back the letter and we will get 5 + 'A' = 'F'
That is the whole magic.
But what to do with an overflow, beyond 'Z'. This can be handled by a simple modulo division. Let us look at 'Z' + 1. We do 'Z' - 'A' = 25, then +1 = 26 and now, modulo 26 = 0. At the end again plus 'A' will be 'A'.
And so on and so on. The resulting formula is: (c - 'A' + key) % 26 +'A'
Next, what with negative keys? This is also simple. Assume an 'A' and key=-1.
Result will be a 'Z'. But this is the same as shifting positions 25 to the right. So, we can simply convert a negative key to a positive shift. The simple statement will be:
if (key < 0) key = (26 + (key % 26)) % 26;
With the above formular, there is even no need to check for a negative values. It will work for positive and negative values.
So, key = (26 + (key % 26)) % 26; will always work, for encrpytion and decrytion, for positive and negative keys.
Some extended information: Please have a look at any ASCII table and remeber, what we said above. We found out already, that any uppercase and lowercase character differ by 32. Or, if you look again to the binary representation:
char dec bin char dec bin
'A' 65 0100 0001 'a' 97 0110 0001
'B' 66 0100 0010 'b' 98 0110 0010
'C' 67 0100 0011 'b' 99 0110 0011
. . .
So, if you already know that a character is alpha, then the only difference between upper- and lowercase is bit number 5. If we want to know, if char is lowercase, we can get this by masking this bit. c & 0b0010 0000. Which is equal to c & 32 or c & 0x20.
If we want to operater on either uppercase or lowercase characters, then we can mask the "case" away. With c & 0b00011111 or c & 31 or c & 0x1F we will get always equivalents for uppercase charcters, already normalized to start with value 1.
char dez bin Masking char dez bin Masking
'A' 65 0100 0001 & 0x1b = 1 'a' 97 0110 0001 & 0x1b = 1
'B' 66 0100 0010 & 0x1b = 2 'b' 98 0110 0010 & 0x1b = 2
'C' 67 0100 0011 & 0x1b = 3 'b' 99 0110 0011 & 0x1b = 3
. . .
So, if we use an alpha character, mask it, and subtract 1, then we get as a result 0..25 for any upper- or lowercase character.
Again, I would like tor repeat the key handling. Positive keys will encrypt a string, negative keys will decrypt a string. But, as said above, negative keys can be transformed into positive ones. Example:
Shifting by -1 is same as shifting by +25
Shifting by -2 is same as shifting by +24
Shifting by -3 is same as shifting by +23
Shifting by -4 is same as shifting by +22
So,it is very obvious that we can calculate an always positive key by: 26 + key. For negative keys, this will give us the above offsets.
And for positve keys, we would have an overflow over 26, which we can elimiate by a modulo 26 division:
'A'--> 0 + 26 = 26 26 % 26 = 0
'B'--> 1 + 26 = 27 27 % 26 = 1
'C'--> 2 + 26 = 28 28 % 26 = 2
'D'--> 3 + 26 = 29 29 % 26 = 3
--> (c + key) % 26 will eliminate overflows and result in the correct new en/decryptd character.
And, if we combine this with the above wisdom for negative keys, we can write: ((26+(key%26))%26) which will work for all positive and negative keys.
If we now implement all above gathered wisdom in code, we can come up with bascically one C++ statement for the whole encryption and decryption, using std::transform:
std::string caesar(const std::string& in, int key) {
std::string res(in.size(), ' ');
std::transform(in.begin(), in.end(), res.begin(), [&](char c) {return std::isalpha(c) ? (char)((((c & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | (c & 32)) : c; });
return res;
}
This will do, what we described above:
(c & 31) - 1 will normalize a character. Meaning, convert to uppercase and to a range of 0-25
((26 + (key % 26)) % 26)) % 26 will do the key shift.
+ 65 will convert the nomalized value (0-25) back to a letter ('A'-'Z')
| (c & 32)) : c This will restore the lower case, if the letter was lower case before.
Now, we derived a complete algorithm and function for encryption and decryption using Caeser Cypher.
.
Next is splitting up the message in 5 parts.
The requirement was:
If possible the message will be evenly split between the five runners; if not possible, parts 1, 2, 3, 4 will be longer and part 5 shorter. The fifth part can have length equal to the other ones or shorter.
This can again be achieved with integer and modulo division. Basically, we will do an integer division to get the number of letters for each of the 5 chunks. Then we use a modulo division, to get the rest.
It is clear, but I will repeat it. If we do an integer division by 5, then the rest can be max 4. And this rest can then be distributed and added 1 by one to other chunks. Let us make an example using 23.
23 % 5 = 4 So, initially each chunk will be 4 letters long
Chunk 1: 4
Chunk 2: 4
Chunk 3: 4
Chunk 4: 4
Chunk 5: 4
------------
Sum: 20 // The rest, 3 is missing
Rest can be calculated with:
23 % 5 = 3 // So, we have a rest or remainder of 3. This we will distribute now:
Remainder = 3
Chunk 1: 4 + 1 = 5 3 - 1 = 2
Chunk 2: 4 + 1 = 5 2 - 1 = 1
Chunk 3: 4 + 1 = 5 1 - 1 = 0 Now everything was distributed
Chunk 4: 4 4
Chunk 5: 4 4
-------------------
Sum: 23
We now know, how chunksizes can be calculated.
For splitting the original strings into substrings, we can use the corresponding std::strings substr function, which is described here. You see, that we need to calculate a "start position" and a "length" value. Let us write a short piece of code for that.
#include <iostream>
#include <array>
#include <string>
constexpr std::size_t NumberOfChunks = 5u;
struct SDefs {
struct SDef {
std::size_t startPosition{}; // For substr function, we need a start position
std::size_t count{}; // and a count aof characters
};
std::array<SDef, NumberOfChunks> sDefs{}; // We have an array of 5 for this Positions and Counts
void calculate(const std::string& s) { // Calculation function
const size_t chunk = s.size() / NumberOfChunks; // Calculate the basic chunksize of all chunks
size_t remainder = s.size() % NumberOfChunks; // Calculate the rest that needs to be distributed
for (std::size_t startPos{}; SDef & sdef : sDefs) { // Calculate all positions and counts in a loop
sdef.startPosition = startPos; // Set startposition
sdef.count = chunk + (remainder ? 1 : 0); // And the chunk size, including potential distributed remainder
startPos += sdef.count; // Next startposition
if (remainder) --remainder; // And next remainder, if any
}
}
SDef& operator[](const std::size_t i) { return sDefs[i]; } // Easier accessibility
};
// Test code
int main () {
SDefs sdefs{};
std::string test{ "12345678901234567890123" };
sdefs.calculate(test);
for (std::size_t i{}; i < NumberOfChunks; ++i)
std::cout << "Chunk " << i+1 << " Start position: " << sdefs[i].startPosition << "\tCount: " << sdefs[i].count << '\n';
}
.
Finally: The transmission of the key. For encrypting, we simply take the first character of the text, or, in our case the substring. and then apply the encryption/decryption function on that to get the second letter.
And because the requirement was to use lower case characters, we set the 5th bit for the characters.
For decryption, in order to get the key, we need to subtract the second letter from the first. Thats all. Then we can invert it and use our encryption/decryption function again.
By the way. This method is dangerous and easy to hack, because you have always repeating letters at the beginning of a chunk.
For the final result, we need to add a little bit of house keeping code.
Then, lets_put everything together and create some program:
#include <iostream>
#include <array>
#include <string>
#include <algorithm>
#include <cctype>
constexpr std::size_t NumberOfChunks = 5u; // Maybe modified to whatever you need
// ---------------------------------------------------------------------------------------------------------
// Chunk calculator
struct SDefs {
struct SDef {
std::size_t startPosition{}; // For substr function, we need a start position
std::size_t count{}; // and a count aof characters
};
std::array<SDef, NumberOfChunks> sDefs{}; // We have an array of 5 for this Positions and Counts
void calculate(const std::string& s) { // Calculation function
const size_t chunk = s.size() / NumberOfChunks; // Calculate the basic chunksize of all chunks
size_t remainder = s.size() % NumberOfChunks; // Calculate the rest that needs to be distributed
for (std::size_t startPos{}; SDef & sdef : sDefs) { // Calculate all positions and counts in a loop
sdef.startPosition = startPos; // Set startposition
sdef.count = chunk + (remainder ? 1 : 0); // And the chunk size, including potential distributed remainder
startPos += sdef.count; // Next startposition
if (remainder) --remainder; // And next remainder, if any
}
}
SDef& operator[](const std::size_t i) { return sDefs[i]; } // Easier accessibility
};
// ---------------------------------------------------------------------------------------------------------
// Caesar Cypher
std::string caesar(const std::string& in, int key) {
std::string res(in.size(), ' ');
std::transform(in.begin(), in.end(), res.begin(), [&](char c) {return std::isalpha(c) ? (char)((((c & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | (c & 32)) : c; });
return res;
}
// Get a prefix, based on a given key
std::string getKeyPrefix(const std::string& s, const int key) {
std::string prefix("AA");
if (auto i = std::find_if(s.begin(), s.end(), std::isalpha); i != s.end()) {
prefix[0] = *i |32;
prefix[1] = (char)((((*i & 31) - 1 + ((26 + (key % 26)) % 26)) % 26 + 65) | 32);
}
return prefix;
}
// ---------------------------------------------------------------------------------------------------------
std::string test{"This was a major hack. What a pity that nobody will read or value it."};
int main() {
std::cout << "\nPlease enter a key: ";
if (int key{}; std::cin >> key) {
// Here we will store our encrypter and later decypted messages
std::array<std::string, NumberOfChunks> messages{};
// Here we will calculate the substrings properties
SDefs sdef{};
sdef.calculate(test);
// Encryption
for (std::size_t i{}; std::string& message : messages) {
// Get substring
const std::string sub = test.substr(sdef[i].startPosition, sdef[i].count);
// Encrypt sub string text
message = getKeyPrefix(sub, key) + caesar(sub,key);
// Debug output
std::cout << "Encrypted Message chunk " << i++ << ":\t" << message << '\n';
}
// Decryption
std::cout << "\n\nDecrypted Message:\n\n";
for (std::string& message : messages) {
// get key, inverted
int dkey = message[0] - message[1];
// Get substring
std::string sub = message.substr(2);
// Derypt sub string text
message = caesar(sub, dkey);
// Debug output
std::cout << message;
}
std::cout << "\n\n";
}
else
std::cerr << "\n\n***Error: Invalid input\n\n";
}
Have fun.
Checksum: fkems hajk eks ἀρμιν μοντιγνι qod krtd ghja

read little endian 16 bit unsigned integer

I'm looking into parsing terminfo database files, which are a type of binary files. You can read about its storage format by your own and confirm the problem I'm facing.
The manual says -
The header section begins the file. This section contains
six short integers in the format described below. These
integers are
(1) the magic number (octal 0432);
...
...
Short integers are stored in two 8-bit bytes. The first
byte contains the least significant 8 bits of the value,
and the second byte contains the most significant 8 bits.
(Thus, the value represented is 256*second+first.) The
value -1 is represented by the two bytes 0377, 0377; other
negative values are illegal. This value generally means
that the corresponding capability is missing from this
terminal. Machines where this does not correspond to the
hardware must read the integers as two bytes and compute
the little-endian value.
The first problem while parsing this type of input is that it fixes the size to 8 bits, so the plain old char cannot be used since it doesn't guarantees the size to be exactly 8 bits. So I was lookin 'Fixed width integer types' but again was faced with dillema of choosing b/w int8_t or uint8_t which clearly states - "provided only if the implementation directly supports the type". So what should I choose so that the type is portable enough.
The second problem is there is no buffer.readInt16LE() method in c++ standard library which might read 16 bytes of data in Little Endian format. So how should I proceed forward to implement this function again in a portable & safe way.
I've already tried reading it with char data type but it definitely produces garbage on my machine. Proper input can be read by infocmp command eg - $ infocmp xterm.
#include <fstream>
#include <iostream>
#include <vector>
int main()
{
std::ifstream db(
"/usr/share/terminfo/g/gnome", std::ios::binary | std::ios::ate);
std::vector<unsigned char> buffer;
if (db) {
auto size = db.tellg();
buffer.resize(size);
db.seekg(0, std::ios::beg);
db.read(reinterpret_cast<char*>(&buffer.front()), size);
}
std::cout << "\n";
}
$1 = std::vector of length 3069, capacity 3069 = {26 '\032', 1 '\001', 21 '\025',
0 '\000', 38 '&', 0 '\000', 16 '\020', 0 '\000', 157 '\235', 1 '\001',
193 '\301', 4 '\004', 103 'g', 110 'n', 111 'o', 109 'm', 101 'e', 124 '|',
71 'G', 78 'N', 79 'O', 77 'M', 69 'E', 32 ' ', 84 'T', 101 'e', 114 'r',
109 'm', 105 'i', 110 'n', 97 'a', 108 'l', 0 '\000', 0 '\000', 1 '\001',
0 '\000', 0 '\000', 1 '\001', 0 '\000', 0 '\000', 0 '\000', 0 '\000',
0 '\000', 0 '\000', 0 '\000', 0 '\000', 1 '\001', 1 '\001', 0 '\000',
....
....
The first problem while parsing this type of input is that it fixes the size to 8 bits, so the plain old char cannot be used since it doesn't guarantees the size to be exactly 8 bits.
Any integer that is at least 8 bits is OK. While char isn't guaranteed to be exactly 8 bits, it is required to be at least 8 bits, so as far as size is concerned, there is no problem other than you may in some cases need to mask the high bits if they exist. However, char might not be unsigned, and you don't want the octets to be interpreted as signed values, so use unsigned char instead.
The second problem is there is no buffer.readInt16LE() method in c++ standard library which might read 16 bytes of data in Little Endian format. So how should I proceed forward to implement this function again in a portable & safe way.
Read one octet at a time into an unsigned char. Assign the first octet to the variable (that is large enough to represent at least 16 bits). Shift the bits of the second octet left by 8 and assign to the variable using the compound bitwise or.
Or better yet, don't re-implement it, but use an third party existing library.
I've already tried reading it with char data type but it definitely produces garbage on my machine.
Then your attempt was buggy. There is no problem inherent with char that would cause garbage output. I recommend using a debugger to solve this problem.

UDP receive data as unsigned char

I am a trying to receive some data from network using UDP and parse it.
Here is the code,
char recvline[1024];
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
for(int i=0;i<n;i++)
cout << hex <<static_cast<short int>(recvline[i])<<" ";
Printed the output,
19 ffb0 0 0 ff88 d 38 19 48 38 0 0 2 1 3 1 ff8f ff82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0
But I am expecting the output like,
19 b0 0 0 88 d 38 19 48 38 0 0 2 1 3 1 8f 82 5 40 20 16 6 6 22 36 6 2c 0 0 0 0 0 0 0 0
The ff shouldn't be there on printed output.
Actually I have to parse this data based on each character,
Like,
parseCommand(recvline);
and the parse code looks,
void parseCommand( char *msg){
int commId=*(msg+1);
switch(commId){
case 0xb0 : //do some operation
break;
case 0x20 : //do another operation
break;
}
}
And while debugging I am getting commId=-80 on watch.
Note:
In Linux I am getting successful output with the code, note that I have used unsigned char instead char for the read buffer.
unsigned char recvline[1024];
int n=recvfrom(sockfd,recvline,1024,0,NULL,NULL);
Where as in Windows recvfrom() not allowing the second argument as unsigned it giving build error, so I chose char
Looks like you might be getting the correct values, but your cast to short int during printing sign-extends your char value, causing ff to be propogated to the top byte if the top bit of your char is 1 (i.e. it is negative). You should first cast it to unsigned type, then extend to int, so you need 2 casts:
cout << hex << static_cast<short int>(static_cast<uint8_t>(recvline[i]))<<" ";
I have tested this and it behaves as expected.
In response to your extension: the data read is fine, it is a matter of how you interpret it. To parse correctly you should:
uint8_t commId= static_cast<uint8_t>(*(msg+1));
switch(commId){
case 0xb0 : //do some operation
break;
case 0x20 : //do another operation
break;
}
As you store your data in a signed data type conversions/promotion to bigger data types will first sign extend the value (filling the high order bits with the value of the MSB) even if it then gets converted to unsigned datatypes.
One solution is to define recvline as uint8_t[] in the first place an cast it to char* when passing it to the recvfrom function. That way, you only have to cast it once and you are using the same code in your windows and linux version. Also uint8_t[] is (at least to me) a clear indication that you are using the array as raw memory instead of a string of some kind.
Another possibility is to simply perform a bitwise And: (recvline[i] & 0xff). Thanks to automatic integral promotion this doesn't even require a cast.
Personal Note:
It is really annoying that the C and C++ standards don't provide a separate type for raw memory (yet), but with any luck well get a byte type in a future standard revision.

C++ Encoding Numbers

I am currently working on sending data to a receiving party based on mod96 encoding scheme. Following is the request structure to be sent from my side:
Field Size Type
1. Message Type 2 "TT"
2. Firm 2 Mod-96
3. Identifier Id 1 Alpha String
4. Start Sequence 3 Mod-96
5. End Sequence 3 Mod-96
My doubt is that the sequence number can be greater than 3 bytes. Suppose I have to send numbers 123 and 123456 as start and end sequence numbers, how to encode it in mod 96 format . Have dropped the query to the receiving party, but they are yet to answer it. Can somebody please throw some light on how to go about encoding the numbers in mod 96 format.
Provided there's a lot of missing detail on what you really need, here's how works Mod-96 econding:
You just use printable characters as if they were digits of a number:
when you encode in base 10 you know that 123 is 10^2*1 + 10^1*2 + 10^0*3
(oh and note that you arbitrary choose that 1's value is really one: value('1') = 1
when you encode in base 96 you know that 123 is
96^2*value('1')+ 96^2*value('2')+96^0*value('3')
since '1' is the ASCII character #49 then value('1') = 49-32 = 17
Encoding 3 printable characters into a number
unsigned int encode(char a, char b, char c){
return (a-32)*96*96 + (b-32)*96 + (c-32);
}
Encoding 2 printable characters into a number
unsigned int encode(char a, char b){
return (b-32)*96 + (c-32);
}
Decoding a number into 2 printable characters
void decode( char* a, char*b, unsigned int k){
* b = k % 96 +32;
* a = k / 96 +32;
}
Decoding a number into 3 printable characters
void decode( char* a, char*b, char*c, unsigned int k){
* c = k % 96 +32;
k/= 96;
* b = k % 96 +32;
* a = k/96 +32;
}
You also of course need to check that characters are printable (between 32 and 127 included) and that numbers you are going to decode are less than 9216 (for 2 characters encoded) and 884736(for 3 characters encoded).
You know the final size would be 6 bytes:
Size 2 => max of 9215 => need 14 bits storage (values up to 16383 unused)
Size 3 => max of 884735 => need 17 bits storage (values up to 131071 unused)
Your packet needs 14+17+17 bits of memory (wich is 48 => exactly 6 bytes) bits storage just for Mod-96 stuff.
Observation:
Instead of 3 fields of sizes(2+3+3) we could have used one field of size(8) => we would finally use 47 bits ( but is still rounded up to 6 bytes)
If you still store each encoded number into a integer number of bytes you would use the same amount of memory (14 bits fits into 2 bytes, 17 bits fits into 3 bytes) used by storing chars directly.

Passing non integer input through console

I have this code :
int obj;
while ( std::cin >> obj )
{
std::cout << obj << std::endl ;
int temp = obj ;
++ temp;
std::cout << temp << std::endl ;
}
When I give proper integer inputs, I understand the output.
eg. If I get 12 as input, I see something like this on console :
12
12
13
But, if I give some integers with white spaces as input, I can't seem to understand the output.
eg. If I give 12 12 12 12 as input, I see this on console :
12 12 12 12
12
13
12
13
12
13
12
13
Can someone please explain ?
The first example includes your input.
input
12
output
12
13
The second example is exactly this, multiplied 4 times, for each of the 4 numbers received as input. The seperator is "whitespace" - spaces, new lines or tabs. It is not a "non integer", but rather "four integers":
The input:
12 12 12 12
is equivalent to
12
12
12
12
output:
12
13
12
13
12
13
12
13
The loop reads whatever the input is, only after you hit "enter". So in the first case, it reads one value 12, prints 12 then 13 for the updated value in temp, then goes back waiting for you to type more numbers.
In the second case, it reads 12, prints 12 & 13, then goes back, reads another 12, prints 12 & 13, and so on another 2 times. Then goes back waiting for your to type more data.
Note that whitespace is a proper separator for your input. If you want it to go wrong, try typing 12a, in which case it will print 12 & 13 forever (well, until you get bored and stop it), since it will "stop reading" at the 'a' without updating obj - and because nothing in the loop clears out the a, it keeps going.
When you add the space, it takes them as separate values. And run the while loop for each of them.
int obj;
cin >> obj;
cin reads valid integer data from your input until it finds a character that does not belong to an integer, or there is no more data. In your first example, cin hits the end of your input and returns the number. In your second example, cin reads the input from the string "12 12 12 12", extracts the first integer from your input stream and writes it to obj. In the next run of your while loop, cin is confronted with the string "12 12 12" (since it has extracted/removed the first number from your input stream) and the story continues until there is no more input to read from.