I have 3 sensors that each provide either 0 or 1 (repeatedly in a loop). They are stored individually as int variables. These are then printed using the following:
print ("%d%d%d", Sensor1, Sensor2, Sensor3);
I want to store each combination (ex: 010, 001, 110, etc.) temporarily so that I can use it do something else (I want to have a switch or something eventually where I can do a different operation depending on the value of the sensor combination). I can't store it as an int since that drops the 0s in front.
How can I store these combinations?
You can use structure bit field for this.
struct Bit{
bool Sensor1 : 1;
bool Sensor2 : 1;
bool Sensor3 : 1;
};
int main(void)
{
struct Bit bit = {0, 1, 0};
printf ("%d%d%d", bit.Sensor1, bit.Sensor2, bit.Sensor3);
}
So you have
int Sensor1, Sensor2, Sensor3;
// have code to initialize above variables to 0 or 1
To store these as one integer in base 10, assuming they really all are 0 or 1, you can do:
int Sensors_10 = Sensor1 * 100 + Sensor2 * 10 + Sensor3;
And then to get them back:
Sensor1 = Sensors_10 / 100 % 10;
Sensor2 = Sensors_10 / 10 % 10;
Sensor3 = Sensors_10 % 10;
Obviously order of sensors can be whatever, as long as it matches between packing and unpacking.
But, you only need 1 bit to store each sensor, so could use binary:
int Sensors_2 = Sensor1 * 4 + Sensor2 * 2 + Sensor3;
...
Sensor1 = Sensors_2 / 4 % 2;
Sensor2 = Sensors_2 / 4 % 2;
Sensor3 = Sensors_2 % 2;
But, with computer binary numbers are special, so the binary version is more commonly written like this:
int Sensors_2 = Sensor1 << 2 | Sensor2 << 1 | Sensor3;
...
Sensor1 = Sensors_2 >> 2 & 1;
Sensor2 = Sensors_2 >> 1 & 1;
Sensor3 = Sensors_2 & 1;
Where |, <<, >> and & are bitwise OR, shift and AND operators, and explaining what they do is beyond scope of this question, but one note about them: When there are no "overlapping" one-bits and numbers are positive, then result of | is same as result of +.
Answer of haccks covers how to make C compiler do this for you, without doing your own bit manipulation.
To print Sensors_10 with leading zeros, you can do printf("%03d", Sensors_10);. C standard library does not have a way to print binary numbers directly, so you need your own code to print the bits one-by-one, so you might as well printf("%d%d%d", Sensor1, Sensor2, Sensor3); then.
You can use a 2D int array to store the values and use it later.
E.g int sen_value[1000][3]; use it in the loop to store the values.
Example how you can use it in loop:
#include <stdio.h>
int main ()
{
int i;
int sen_value[10][3];
for(i=0;i<10;i++)
{
//Assigning the values
sen_value[i][0] = 0;
sen_value[i][1] = 0;
sen_value[i][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[i][0],sen_value[i][1],sen_value[i][2]);
}
return 0;
}
Or you can use it just once and then reset it after each operation, For example:
#include <stdio.h>
int main ()
{
int sen_value[1][3];
//Assigning the values
sen_value[0][0] = 0;
sen_value[0][1] = 0;
sen_value[0][2] = 0;
//Use the way you want
printf("%d %d %d\n",sen_value[0][0],sen_value[0][1],sen_value[0][2]);
return 0;
}
If you are using a linux environment then by using the command you can easily save the output that are displayed in your console.
Let here sensor.c be your source file Then,
$ gcc -o a sensor.c
$ ./a > senser.txt
Then you have a .txt file with all output stored in a txt file. And these can be again used as inputs in your other.c files like :
$ gcc -o other other.c
$ ./other < senser.txt
If you want to store those sensor1,sensor2,sensor3 internally and use internally then you can simply use the arrays or Structure like :
main(){
int Sensor[1][3];
Sensor[0][0] = 0;
Sensor[0][1] = 1;
Sensor[0][2] = 0;
print ("%d%d%d", Sensor[0][0], Sensor[0][1], Sensor[0][2]);
}
While the leading zeroes of an integer are not displayed when printed, that does not mean they are "dropped"; they are merely implicit - that is a matter of the format specifier used in teh output of the value rather than the zeros not being present. An int is always a fixed number of binary digits.
Consider:
uint32_t sensor_state = (sensor3 << 3) | (sensor2 << 1) | sensor1 ;
Note that uint32_t is a type alias for an unsigned integer 32 bits in length. It is defined by including the <stdint.h> header file. In this case a plain int would work, but when you are dealing with data at the bit level it is good to be explicit (and unsigned). Here of course a uint8_t would work too, and if your target is an 8 bit device, I suggest you use that.
Here sensor_state is a binary combination of the three sensor values and will have one of the following values:
Sensors sensor_state
3 2 1 binary decimal hexadecimal
---------------------------------------
0 0 0 0000 0 0x00
0 0 1 0001 1 0x01
0 1 0 0010 2 0x02
0 1 1 0011 3 0x03
1 0 0 0100 4 0x04
1 0 1 0101 5 0x05
1 1 0 0110 6 0x06
1 1 1 0111 7 0x07
So you can switch on any combination:
switch( sensor_state )
{
case 0x00 :
...
break ;
case 0x01 :
...
break ;
case 0x02 :
...
break ;
...
case 0x07 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You might usefully create an enumeration for each combination:
enum eSensorStates
{
NO_SENSOR = 0,
SENSOR1,
SENSOR2,
SENSOR12,
SENSOR3,
SENSOR13,
SENSOR23,
SENSOR123
}
Then you can write:
switch( sensor_state )
{
case NO_SENSOR :
...
break ;
case SENSOR1:
...
break ;
case SENSOR2:
...
break ;
...
case SENSOR123 :
...
break ;
default :
// unexpected invalid combination
break ;
}
You may of course use enumeration names that make specific sense in your application - that reflect the meaning or action for each combination rather than the generic names I have chosen.
Related
I'm working on a crackme , and having a bit of trouble making sense of the flag I'm supposed to retrieve.
I have disassembled the binary using radare2 and ghidra , ghidra gives me back the following pseudo-code:
undefined8 main(void)
{
long in_FS_OFFSET;
double dVar1;
double dVar2;
int local_38;
int local_34;
int local_30;
int iStack44;
int local_28;
undefined2 uStack36;
ushort uStack34;
char local_20;
undefined2 uStack31;
uint uStack29;
byte bStack25;
long local_10;
local_10 = *(long *)(in_FS_OFFSET + 0x28);
__printf_chk(1,"Insert flag: ");
__isoc99_scanf(&DAT_00102012,&local_38);
uStack34 = uStack34 << 8 | uStack34 >> 8;
uStack29 = uStack29 & 0xffffff00 | (uint)bStack25;
bStack25 = (undefined)uStack29;
if ((((local_38 == 0x41524146) && (local_34 == 0x7b594144)) && (local_30 == 0x62753064)) &&
(((iStack44 == 0x405f336c && (local_20 == '_')) &&
((local_28 == 0x665f646e && (CONCAT22(uStack34,uStack36) == 0x40746f31)))))) {
dVar1 = (double)CONCAT26(uStack34,CONCAT24(uStack36,0x665f646e));
dVar2 = (double)CONCAT17((undefined)uStack29,CONCAT43(uStack29,CONCAT21(uStack31,0x5f)));
__printf_chk(0x405f336c62753064,1,&DAT_00102017);
__printf_chk(dVar1,1,"y: %.30lf\n");
__printf_chk(dVar2,1,"z: %.30lf\n");
dVar1 = dVar1 * 124.8034902710365;
dVar2 = (dVar1 * dVar1) / dVar2;
round_double(dVar2,0x1e);
__printf_chk(1,"%.30lf\n");
dVar1 = (double)round_double(dVar2,0x1e);
if (1.192092895507812e-07 <= (double)((ulong)(dVar1 - 4088116.817143337) & 0x7fffffffffffffff))
{
puts("Try Again");
}
else {
puts("Well done!");
}
}
if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
/* WARNING: Subroutine does not return */
__stack_chk_fail();
}
return 0;
}
It is easy to see that there's a part of the flag in plain-sight , but the other part is a bit more interesting :
if (1.192092895507812e-07 <= (double)((ulong)(dVar1 - 4088116.817143337) & 0x7fffffffffffffff))
From what I understand , I have to generate the missing part of the flag depending on this condition . The problem is that I absolutely have no idea how to do this .
I can assume this missing part is 8 bytes of size , according to this line :
dVar2=(double)CONCAT17((undefined)uStack29,CONCAT43(uStack29,CONCAT21(uStack31,0x5f)));`
Considering flags are usually ascii , with some special characters , let's say , each byte will have values from 0x21 to 0x7E , that's almost 8^100 combinations , which will clearly take too much time to compute.
Do you guys have an idea on how I should proceed to solve this ?
Edit : Here is the link to the binary : https://filebin.net/dpfr1nocyry3sijk
You can tweak the Ghidra reverse result by edit variable type. Based on scanf const string %32s your local_38 should be char [32].
Before the first if, there are some char swap.
And the first if statment give you a long constrain of flag
At this point, you can confirm part of flag is FARADAY{d0ubl3_#nd_f1o#t, then is ther main part of this challenge.
It print x, y, z based on the flag, but you'll quickly find x and y is constrain by the if, so you only need to solve z to get the flag, so you think you need to bruteforce all double value limit by printable ascii.
But there are a limitaion in if statment says byte0 of this double must be _ and a math constrain there, simple math tell dVar2 - 4088116.817143337 <= 1.192092895507813e-07 and it comes dVar2 is very close 4088116.817143337
And byte 3 and byte 7 in this double will swap
By reverse result: dVar2 = y*y*x*x/z, solve this equation you can say z must near 407.2786840401004 and packed to little endian is `be}uty#. Based on double internal structure format, MSB will affect exponent, so you can make sure last byte is # and it shows byte0 and byte3 is fixed now by constrain and flag common format with {} pair.
So finally, you only need to bureforce 5 bytes of printable ascii to resolve this challenge.
import string, struct
from itertools import product
possible = string.ascii_lowercase + string.punctuation + string.digits
for nxt in product(possible, repeat=5):
n = ''.join(nxt).encode()
s = b'_' + n[:2] + b'}' + n[2:] + b'#'
rtn = struct.unpack("<d", s)[0]
rtn = 1665002837.488342 / rtn
if abs(rtn - 4088116.817143337) <= 0.0000001192092895507812:
print(s)
And bingo the flag is FARADAY{d0ubl3_#nd_f1o#t_be#uty}
I'm coding a PIC18F252 microcontroller in C. The program should take 3 separate inputs from sensors (run through the ADC first), and then depending on the combination of these 3 inputs it will select an output from the switch statement.
So for example, if each sensor outputs a 0, I would want to select the case '000' and execute its instructions. If the middle sensor outputs a 1, I want case 010 etc.
I've looked into doing this using arrays or strings to store the 3 character value, but I don't seem to be able to use the switch statement correctly to compare the input to the case.
It seems that an if/else statement would be a more simplistic way of doing this but I need to use switch.
So can anyone tell me if its possible to compare an array or string with the cases, or if there's any other way to do this? Only other way I can think of would be to assign the input combo to a word variable, but this would require a switch or if/else statement of its own.
If the input values are digital values (0 or 1), you can combine the bits to a single number by bit shifting and bit-wise OR.
Example:
int input1 = 0;
int input2 = 1;
int input3 = 1;
int combined;
/* assuming the values can be 0 or 1 only */
combined = input1 | ( input2 << 1 ) | ( input3 << 2 );
/* or with any non-zero value as TRUE */
combined = (input1 ? 1 << 0 : 0) | (input2 ? 1 << 1 : 0) | ( input3 ? 1 << 2 : 0);
switch(combined)
{
case 0x0: // or GCC extension 0xb000
case 0x1: // or GCC extension 0xb001
case 0x2: // or GCC extension 0xb010
case 0x3: // or GCC extension 0xb011
/* ... */
}
What I need to do is to read binary inputs from a file. The inputs are for example (binary dump),
00000000 00001010 00000100 00000001 10000101 00000001 00101100 00001000 00111000 00000011 10010011 00000101
What I did is,
char* filename = vargs[1];
BYTE buffer;
FILE *file_ptr = fopen(filename,"rb");
fseek(file_ptr, 0, SEEK_END);
size_t file_length = ftell(file_ptr);
rewind(file_ptr);
for (int i = 0; i < file_length; i++)
{
fread(&buffer, 1, 1, file_ptr); // read 1 byte
printf("%d ", (int)buffer);
}
But the problem here is that, I need to divide those binary inputs in some ways so that I can use it as a command (e.g. 101 in the input is to add two numbers)
But when I run the program with the code I wrote, this provides me an output like:
0 0 10 4 1 133 1 44 8 56 3 147 6
which shows in ASCII numbers.
How can I read the inputs as binary numbers, not ASCII numbers?
The inputs should be used in this way:
0 # Padding for the whole file!
0000|0000 # Function 0 with 0 arguments
00000101|00|000|01|000 # MOVE the value 5 to register 0 (000 is MOV function)
00000011|00|001|01|000 # MOVE the value 3 to register 1
000|01|001|01|100 # ADD registers 0 and 1 (100 is ADD function)
000|01|0000011|10|000 # MOVE register 0 to 0x03
0000011|10|010 # POP the value at 0x03
011 # Return from the function
00000110 # 6 instructions in this function
I am trying to implement some sort of like assembly language commands
Can someone please help me out with this problem?
Thanks!
You need to understand the difference between data and its representation. You are correctly reading the data in binary. When you print the data, printf() gives the decimal representation of the binary data. Note that 00001010 in binary is the same as 10 in decimal and 00000100 in binary is 4 in decimal. If you convert each sequence of bits into its decimal value, you will see that the output is exactly correct. You seem to be confusing the representation of the data as it is output with how the data is read and stored in memory. These are two different and distinct things.
The next step to solve your problem is to learn about bitwise operators: |, &, ~, >>, and <<. Then use the appropriate combination of operators to extract the data you need from the stream of bits.
The format you use is not divisible by a byte, so you need to read your bits into a circular buffer and parse it with a state machine.
Read "in binary" or "in text" is quite the same thing, the only thing that change is your interpretation of the data. In your exemple you are reading a byte, and you are printing the decimal value of that byte. But you want to print the bit of that char, to do that you just need to use binary operator of C.
For example:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
struct binary_circle_buffer {
size_t i;
unsigned char buffer;
};
bool read_bit(struct binary_circle_buffer *bcn, FILE *file, bool *bit) {
if (bcn->i == CHAR_BIT) {
size_t ret = fread(&bcn->buffer, sizeof bcn->buffer, 1, file);
if (!ret) {
return false;
}
bcn->i = 0;
}
*bit = bcn->buffer & ((unsigned char)1 << bcn->i++); // maybe wrong order you should test yourself
// *bit = bcn->buffer & (((unsigned char)UCHAR_MAX / 2 + 1) >> bcn->i++);
return true;
}
int main(void)
{
struct binary_circle_buffer bcn = { .i = CHAR_BIT };
FILE *file = stdin; // replace by your file
bool bit;
size_t i = 0;
while (read_bit(&bcn, file, &bit)) {
// here you must code your state machine to parse instruction gl & hf
printf(bit ? "1" : "0");
if (++i >= 7) {
i = 0;
printf(" ");
}
}
}
Help you more would be difficult, you are basically asking help to code a virtual machine...
So I have to find the set bits (on 1) of an unsigned char variable in C?
A similar question is How to count the number of set bits in a 32-bit integer? But it uses an algorithm that's not easily adaptable to 8-bit unsigned chars (or its not apparent).
The algorithm suggested in the question How to count the number of set bits in a 32-bit integer? is trivially adapted to 8 bit:
int NumberOfSetBits( uint8_t b )
{
b = b - ((b >> 1) & 0x55);
b = (b & 0x33) + ((b >> 2) & 0x33);
return (((b + (b >> 4)) & 0x0F) * 0x01);
}
It is simply a case of shortening the constants the the least significant eight bits, and removing the final 24 bit right-shift. Equally it could be adapted for 16bit using an 8 bit shift. Note that in the case for 8 bit, the mechanical adaptation of the 32 bit algorithm results in a redundant * 0x01 which could be omitted.
The fastest approach for an 8-bit variable is using a lookup table.
Build an array of 256 values, one per 8-bit combination. Each value should contain the count of bits in its corresponding index:
int bit_count[] = {
// 00 01 02 03 04 05 06 07 08 09 0a, ... FE FF
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, ..., 7, 8
};
Getting a count of a combination is the same as looking up a value from the bit_count array. The advantage of this approach is that it is very fast.
You can generate the array using a simple program that counts bits one by one in a slow way:
for (int i = 0 ; i != 256 ; i++) {
int count = 0;
for (int p = 0 ; p != 8 ; p++) {
if (i & (1 << p)) {
count++;
}
}
printf("%d, ", count);
}
(demo that generates the table).
If you would like to trade some CPU cycles for memory, you can use a 16-byte lookup table for two 4-bit lookups:
static const char split_lookup[] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
};
int bit_count(unsigned char n) {
return split_lookup[n&0xF] + split_lookup[n>>4];
}
Demo.
I think you are looking for Hamming Weight algorithm for 8bits?
If it is true, here is the code:
unsigned char in = 22; //This is your input number
unsigned char out = 0;
in = in - ((in>>1) & 0x55);
in = (in & 0x33) + ((in>>2) & 0x33);
out = ((in + (in>>4) & 0x0F) * 0x01) ;
Counting the number of digits different than 0 is also known as a Hamming Weight. In this case, you are counting the number of 1's.
Dasblinkenlight provided you with a table driven implementation, and Olaf provided you with a software based solution. I think you have two other potential solutions. The first is to use a compiler extension, the second is to use an ASM specific instruction with inline assembly from C.
For the first alternative, see GCC's __builtin_popcount(). (Thanks to Artless Noise).
For the second alternative, you did not specify the embedded processor, but I'm going to offer this in case its ARM based.
Some ARM processors have the VCNT instruction, which performs the count for you. So you could do it from C with inline assembly:
inline
unsigned int hamming_weight(unsigned char value) {
__asm__ __volatile__ (
"VCNT.8"
: "=value"
: "value"
);
return value;
}
Also see Fastest way to count number of 1s in a register, ARM assembly.
For completeness, here is Kernighan's bit counting algorithm:
int count_bits(int n) {
int count = 0;
while(n != 0) {
n &= (n-1);
count++;
}
return count;
}
Also see Please explain the logic behind Kernighan's bit counting algorithm.
I made an optimized version. With a 32-bit processor, utilizing multiplication, bit shifting and masking can make smaller code for the same task, especially when the input domain is small (8-bit unsigned integer).
The following two code snippets are equivalent:
unsigned int bit_count_uint8(uint8_t x)
{
uint32_t n;
n = (uint32_t)(x * 0x08040201UL);
n = (uint32_t)(((n >> 3) & 0x11111111UL) * 0x11111111UL);
/* The "& 0x0F" will be optimized out but I add it for clarity. */
return (n >> 28) & 0x0F;
}
/*
unsigned int bit_count_uint8_traditional(uint8_t x)
{
x = x - ((x >> 1) & 0x55);
x = (x & 0x33) + ((x >> 2) & 0x33);
x = ((x + (x >> 4)) & 0x0F);
return x;
}
*/
This produces smallest binary code for IA-32, x86-64 and AArch32 (without NEON instruction set) as far as I can find.
For x86-64, this doesn't use the fewest number of instructions, but the bit shifts and downcasting avoid the use of 64-bit instructions and therefore save a few bytes in the compiled binary.
Interestingly, in IA-32 and x86-64, a variant of the above algorithm using a modulo ((((uint32_t)(x * 0x08040201U) >> 3) & 0x11111111U) % 0x0F) actually generates larger code, due to a requirement to move the remainder register for return value (mov eax,edx) after the div instruction. (I tested all of these in Compiler Explorer)
Explanation
I denote the eight bits of the byte x, from MSB to LSB, as a, b, c, d, e, f, g and h.
abcdefgh
* 00001000 00000100 00000010 00000001 (make 4 copies of x
--------------------------------------- with appropriate
abc defgh0ab cdefgh0a bcdefgh0 abcdefgh bit spacing)
>> 3
---------------------------------------
000defgh 0abcdefg h0abcdef gh0abcde
& 00010001 00010001 00010001 00010001
---------------------------------------
000d000h 000c000g 000b000f 000a000e
* 00010001 00010001 00010001 00010001
---------------------------------------
000d000h 000c000g 000b000f 000a000e
... 000h000c 000g000b 000f000a 000e
... 000c000g 000b000f 000a000e
... 000g000b 000f000a 000e
... 000b000f 000a000e
... 000f000a 000e
... 000a000e
... 000e
^^^^ (Bits 31-28 will contain the sum of the bits
a, b, c, d, e, f, g and h. Extract these
bits and we are done.)
Maybe not the fastest, but straightforward:
int count = 0;
for (int i = 0; i < 8; ++i) {
unsigned char c = 1 << i;
if (yourVar & c) {
//bit n°i is set
//first bit is bit n°0
count++;
}
}
For 8/16 bit MCUs, a loop will very likely be faster than the parallel-addition approach, as these MCUs cannot shift by more than one bit per instruction, so:
size_t popcount(uint8_t val)
{
size_t cnt = 0;
do {
cnt += val & 1U; // or: if ( val & 1 ) cnt++;
} while ( val >>= 1 ) ;
return cnt;
}
For the incrementation of cnt, you might profile. If still too slow, an assember implementation might be worth a try using carry flag (if available). While I am in against using assembler optimizations in general, such algorithms are one of the few good exceptions (still just after the C version fails).
If you can omit the Flash, a lookup table as proposed by #dasblinkenlight is likey the fastest approach.
Just a hint: For some architectures (notably ARM and x86/64), gcc has a builtin: __builtin_popcount(), you also might want to try if available (although it takes int at least). This might use a single CPU instruction - you cannot get faster and more compact.
Allow me to post a second answer. This one is the smallest possible for ARM processors with Advanced SIMD extension (NEON). It's even smaller than __builtin_popcount() (since __builtin_popcount() is optimized for unsigned int input, not uint8_t).
#ifdef __ARM_NEON
/* ARM C Language Extensions (ACLE) recommends us to check __ARM_NEON before
including <arm_neon.h> */
#include <arm_neon.h>
unsigned int bit_count_uint8(uint8_t x)
{
/* Set all lanes at once so that the compiler won't emit instruction to
zero-initialize other lanes. */
uint8x8_t v = vdup_n_u8(x);
/* Count the number of set bits for each lane (8-bit) in the vector. */
v = vcnt_u8(v);
/* Get lane 0 and discard other lanes. */
return vget_lane_u8(v, 0);
}
#endif
I saw this line of code today and had no idea what it does.
typedef enum {
SomeOptionKeys = 1 << 0 // ?
} SomeOption;
Some usage or example would be helpful. Thanks!
It looks like it defines an enumerated type that is supposed to contain a set of flags. You'd expect to see more of them defined, like this:
typedef enum {
FirstOption = 1 << 0,
SecondOption = 1 << 1,
ThirdOption = 1 << 2
} SomeOption;
Since they are defined as powers of two, each value corresponds to a single bit in an integer variable. Thus, you can use the bitwise operators to combine them and to test if they are set. This is a common pattern in C code.
You could write code like this that combines them:
SomeOption myOptions = FirstOption | ThirdOption;
And you could check which options are set like this:
if (myOptions & ThirdOption)
{
...
}
The value of SomeOptionKeys is one, this is a useful representation when working with flags:
typedef enum {
flag1 = 1 << 0, // binary 00000000000000000000000000000001
flag2 = 1 << 1, // binary 00000000000000000000000000000010
flag3 = 1 << 2, // binary 00000000000000000000000000000100
flag4 = 1 << 3, // binary 00000000000000000000000000001000
flag5 = 1 << 4, // binary 00000000000000000000000000010000
// ...
} SomeOption;
Whit way each flag has only one bit set, and they could be represented in a bitmap.
Edit:
Although, I have to say, that I might be missing something, but it seems redundent to me to use enums for that. Since you lose any advantage of enums in this configuration, you may as well use #define:
#define flag1 (1<<0)
#define flag2 (1<<1)
#define flag3 (1<<2)
#define flag4 (1<<3)
#define flag5 (1<<4)
It just sets the enum to the value 1. It is probably intended to indicate that the values are to be powers of 2. The next one would maybe be assigned 1 << 1, etc.
<< is the left shift operator. In general, this is used when you want your enums to mask a single bit. In this case, the shift doesn't actually do anything since it's 0, but you might see it pop up in more complex cases.
An example might look like:
typedef enum {
OptionKeyA = 1<<0,
OptionKeyB = 1<<1,
OptionKeyC = 1<<2,
} OptionKeys;
Then if you had some function that took an option key, you could use the enum as a bitmask to check if an option is set.
int ASet( OptionKeys x){
return (x & OptionKeyA);
}
Or if you had a flag bitmap and wanted to set one option:
myflags | OptionKeyB