So I came across this question somewhere:
Case 1:
int a;
a = 1, 2, 3;
printf("%d", a);
Case 2:
int a = 1, 2, 3;
printf("%d", a);
The explanation says:
The second case gives error because comma is used as a separator, In first case = takes precedence over , so it is basically (a=1), 2, 3;
But I want to ask why does = not take precedence over , in Case 2?
It is not just a question of precedence, but rather a question of the language grammar: the = in both cases is not the same operator:
in the declaration int a = 1, 2, 3;, the = token introduces an initializer which cannot be a comma expression. The , ends the initializer and the compiler issues an error because 2 is not a valid identifier for another variable.
in the statement a = 1, 2, 3;, a = 1, 2, 3 is an expression, parsed as ((a = 1), 2), 3 because = has higher precedence than ,. = is the assignment operator whose right hand side is an expression, this assignment is the left operand of a comma operator , followed by a constant expression 2, a = 1, 2 itself the left operand of the final , operator whose right operand is 3. The statement is equivalent to ((a = 1), 2), 3);, which simplifies into a = 1;.
This
int a = 1, 2, 3;/* not a valid one */
is wrong because since = has higher priority, so it become int a = 1 internally and there is no name for 2 and 3 thats why this statement is not valid and cause compile time error.
To avoid this you might want to use
int a = (1, 2, 3); /* evaluate all expression inside () from L->R and assign right most expression to a i.e a=3*/
And here
int a;
a = 1,2,3;
there are two operator = and , and see man operator. The assignment operator = has higher priority than comma operator. So it becomes a=1.
a = 1,2,3;
| L--->R(coma operator associativity)
this got assigned to a
for e.g
int x = 10, y = 20,z;
z = 100,200,y=30,0; /* solve all expression form L to R, but finally it becomes z=100*/
printf("x = %d y = %d z = %d\n",x,y,z);/* x = 10, y = 30(not 20) z = 100 */
z = (100,200,y=30,0); /* solve all expression form L to R, but assign right most expression value to z*/
Inside variable declarations (as case 1) comma are used to declare several variables, for example:
int a,b=2,c=b+1,d; //here only b and c were initialized
An statement in C/C++ could be a list of comma separated expressions (this is what happens in case 2):
a=b+1, c+=2, b++, d = a+b+c, 3, d; //these are expressions, remember one literal is an expression too!!!
NOTE : comma (,) is a compile time operator,
from my side their is Four cases that you can come across :
case 1
int a = 1, 2, 3; // invalid case cause too many initializers
case 2
int a = (1, 2, 3); // valid case
/* You can expand this line as a :
1;
2;
int a = 3;
*/
case 3
int a;
a = 1, 2, 3; // valid case
/* You can expand this line as a :
a = 1; // expression 1
2; // expression 2
3; // expression 3
*/
case 4
int a;
a = ( 1, 2, 3);// valid case
/* You can expand this line as a :
1; // expression 1
2; // expression 2
a = 3; // expression 3
*/
In above cases in place of 1, 2, 3 we can use any valid expression in C, explore more!!
This question already has answers here:
Variable number of arguments in C++?
(17 answers)
Closed 8 years ago.
I want to accept some inputs for a program,the inputs are integer values.
The condition on accepting the inputs is number of inputs is not fixed
but maximum number of inputs to be taken is fixed.
for example lets say the maximum input limit is 15 inputs.
So I should be able to accept "n" inputs where "n" can have any value from 1 to 15.
Is there a way to do this in cpp?
There is a general mechanism in C and C++ for writing functions that accept an arbitrary number of arguments. Variable number of arguments in C++?. However, this will not create a restriction on the number of args or restrict the overloads to a fixed type and it is generally a bit clunky to use (IMO).
It is possible to do something with variadic templates, for instance:
#include <iostream>
#include <vector>
using namespace std;
void vfoo(const std::vector<int> &ints)
{
// Do something with the ints...
for (auto i : ints) cout << i << " ";
cout << endl;
}
template <typename...Ints>
void foo(Ints...args)
{
constexpr size_t sz = sizeof...(args);
static_assert(sz <= 15, "foo(ints...) only support up to 15 arguments"); // This is the only limit on the number of args.
vector<int> v = {args...};
vfoo(v);
}
int main() {
foo(1);
foo(1, 2, 99);
foo(1, 4, 99, 2, 5, -33, 0, 4, 23, 3, 44, 999, -43, 44, 3);
// foo(1, 4, 99, 2, 5, -33, 0, 4, 23, 3, 44, 999, -43, 44, 3, 0); // This will not compile
// You can also call the non-template version with a parameter pack directly:
vfoo({4, 3, 9});
// Downside is that errors will not be great; i.e. .this
// foo(1.0, 3, 99);
// /Users/jcrotinger/Work/CLionProjects/so_variadic_int_function/main.cpp:21:22: error: type 'double' cannot be narrowed to 'int' in initializer list [-Wc++11-narrowing]
// vector<int> v = {args...};
// ^~~~
// /Users/jcrotinger/Work/CLionProjects/so_variadic_int_function/main.cpp:38:5: note: in instantiation of function template specialization 'foo<double, int, int>' requested here
// foo(1.0, 3, 99);
// ^
return 0;
}
The static assert is the only thing that will limit this to 15 arguments. As the comment indicates, type checking is messy since the error message will come not from the function call but from the initialization of the vector.
This does require support for C++ 11's variadic templates.
I'm looking for a function for C/C++ that behaves identically to PHP's md5() function -- pass in a string, return a one-way hash of that string. I'm also open to other algorithms than md5() if they are as secure (or more secure), reasonably fast, and ideally one-way.
The reason I'm searching for said function is for the same purpose I would use PHP's md5() function: to store a one-way hash of a user's password in a database rather than the actual text of the user's password (in case the database's data is ever compromised, the user's passwords would still be relatively secret).
I've spent around two hours searching now. All the code I've found either was for getting an MD5 of file data (instead of just a string), wouldn't compile, was for another programming language, or required an entire library (such as Crypto++, OpenSSL, hashlib++) to be added to my project, some of which are very large (is that really necessary when all I want is just one one-way string hashing function?).
Seeing as how this is a common need, I'm assuming someone has already written and made available exactly what I'm looking for.. can someone point me to it?
Thanks in advance.
Seriously, use a library (OpenSSL is a good choice). They're well-tested, and you can just drop them into your project without having to worry if you get the code right or not. Don't worry about the size of the library, any functions you don't use will not be included in your final executable.
I'd also recommend avoiding MD5, as it has known weaknesses, in favor of something stronger such as SHA-256 or Blowfish.
But whichever algorithm and implementation you go with, do not forget to salt your inputs!
Wikipedia's MD5 simple implementation has easy code and is very fast.
I would recommend it over the above solutions (for MD5 if it must be MD5) because it does not require an external library and the code does not contain #ifdefs
/*
* Simple MD5 implementation
*
* Compile with: gcc -o md5 -O3 -lm md5.c
*
* NOTE: this code only works on little-endian machines.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
// Constants are the integer part of the sines of integers (in radians) * 2^32.
const uint32_t k[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee ,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 ,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be ,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 ,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa ,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 ,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed ,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a ,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c ,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 ,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 ,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 ,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 ,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 ,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 ,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
// leftrotate function definition
#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
// These vars will contain the hash
uint32_t h0, h1, h2, h3;
void md5(uint8_t *initial_msg, size_t initial_len) {
// Message (to prepare)
uint8_t *msg = NULL;
int new_len;
uint32_t bits_len;
int offset;
uint32_t *w;
uint32_t a, b, c, d, i, f, g, temp;
// Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
// r specifies the per-round shift amounts
const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
// Initialize variables - simple count in nibbles:
h0 = 0x67452301;
h1 = 0xefcdab89;
h2 = 0x98badcfe;
h3 = 0x10325476;
// Pre-processing: adding a single 1 bit
//append "1" bit to message
/* Notice: the input bytes are considered as bits strings,
where the first bit is the most significant bit of the byte.[37] */
// Pre-processing: padding with zeros
//append "0" bit until message length in bit ≡ 448 (mod 512)
//append length mod (2 pow 64) to message
for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
new_len /= 8;
msg = (uint8_t*)calloc(new_len + 64, 1); // also appends "0" bits
// (we alloc also 64 extra bytes...)
memcpy(msg, initial_msg, initial_len);
msg[initial_len] = 128; // write the "1" bit
bits_len = 8*initial_len; // note, we append the len
memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
// Process the message in successive 512-bit chunks:
//for each 512-bit chunk of message:
for(offset=0; offset<new_len; offset += (512/8)) {
// break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
w = (uint32_t *) (msg + offset);
#ifdef DEBUG
printf("offset: %d %x\n", offset, offset);
int j;
for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]);
puts("");
#endif
// Initialize hash value for this chunk:
a = h0;
b = h1;
c = h2;
d = h3;
// Main loop:
for(i = 0; i<64; i++) {
if (i < 16) {
f = (b & c) | ((~b) & d);
g = i;
} else if (i < 32) {
f = (d & b) | ((~d) & c);
g = (5*i + 1) % 16;
} else if (i < 48) {
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] + w[g]), r[i]);
a = temp;
}
// Add this chunk's hash to result so far:
h0 += a;
h1 += b;
h2 += c;
h3 += d;
}
// cleanup
free(msg);
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("usage: %s 'string'\n", argv[0]);
return 1;
}
char *msg = argv[1];
size_t len = strlen(msg);
// benchmark
int i;
for (i = 0; i < 1000000; i++) {
md5((uint8_t*)msg, len);
}
//var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
uint8_t *p;
// display result
p=(uint8_t *)&h0;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h0);
p=(uint8_t *)&h1;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h1);
p=(uint8_t *)&h2;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h2);
p=(uint8_t *)&h3;
printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h3);
puts("");
return 0;
}
There is a reference implementation for MD5 in C at the bottom of RFC 1321, which doesn't require any extra libraries.
here is a site that has the MD5 algorithm in many languages:
http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html
also if you use Visual C++, you can use .NET which has encryption support here is some documentation:
http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx#Y0
hope that helps!
SHA-1 is easy. Pseudocode here: http://en.wikipedia.org/wiki/SHA-1
HOWEVER, you need to salt your passwords. This means you save a few bytes of random data in front of the password and hashed password.
General form (salt is fixed length):
salt + sha1(salt + password) = hash
Update from decade later: DO NOT USE. SHA-1 should be aged out now. The collision attack doesn't matter. SHA-1 is currently too fast and a dictionary attack is within range, salt or no salt.
See crypt(). It can do MD5 when passed a specific salt.
The Boost library has a fairly good implementation of the SHA-1 hash function. You can find the source for it here.
For example I have:
int boo[8];
boo[1] = boo[3] = boo[7] = 4;
boo[0] = boo[2] = 7;
boo[4] = boo[5] = boo[6] = 15;
How I should type it as constant values? I saw similar question but it didn't help me.
EDIT:
One more question what about if boo with indexes 0 1 3 4 5 6 7 is constant but boo[2] is not? is it possible to do it?
Is this what you are looking for?
const int boo[] = { 7, 4, 7, 4, 15, 15, 15, 4 };
Get a non-const pointer to one entry in the array like this:
int * foo = (int*)&boo[2];
One not so elegant solution may be:
const int boo[8] = {7,4,7,4,15,15,15,4};
Another solution may be:
int boo_[8];
boo_[1] = boo_[3] = boo_[7] = 4;
boo_[0] = boo_[2] = 7;
boo_[4] = boo_[5] = boo_[6] = 15;
const int * boo = boo_;