-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbitflip.c
More file actions
240 lines (222 loc) · 6.25 KB
/
bitflip.c
File metadata and controls
240 lines (222 loc) · 6.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
Student Name: Marcos Ondruska
Student ID: 2685885
I affirm that I wrote this program without any help from any other
people or sources from the internet.
Program description: this program will take your integer input and
flip the even binary bits, flip the odd binary bits, flip all the bits,
as well as switch all the bits from right to left starting at the first 1. If the -o option is selected,
the output will be to a file, or otherwise it will be to stdout.
example of command line parsing vie bitflip
usage: [-e] [-f] [-a] [-s] [-outputfilename] intval
Marcos Ondruska
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#define INT_SIZE sizeof(uint16_t)
#define INT_BITS INT_SIZE * 8 - 1
int debug = 0;
// count the number of bits in a binary number
int bitCount(uint16_t input)
{
int counter = 0;
while (input > 0)
{
counter++;
input = input >> 1;
}
return counter;
}
// find the first 1 from right to left if a number is even
int evenFirstOne(uint16_t num)
{
int count = 0;
int i = 0;
int bit = 0;
if (num == 0)
{
count = 1; // count must be 0 at return
}
else
{
while (bit != 1)
{ // Looking for first '1'
bit = (num >> i) & 1;
i++;
count++;
}
}
return count - 1;
}
int main(int argc, char **argv)
{
extern char *optarg;
extern int optind;
int c, err = 0;
int eflag = 0, fflag = 0, aflag = 0, sflag = 0, oflag = 0; // flags
char *fname; // Initializing fname
static char usage[] = "usage: %s [-e] [-f] [-a] [-s] [-o outputfilename] intval\n";
uint16_t userInput, eFlagResult, fFlagResult, aFlagResult, sFlagResult; // initializing user input and temp variables for printing to stdout and to file
uint64_t inputCheck; // to check for user input greater than 65535
char collectArg[6];
int numberOfBits = 0, bit = 0; // initializing numberOfBits,and bit
FILE *fptr; // initializing file pointer
while ((c = getopt(argc, argv, "efaso:")) != -1) // options for debug, flipping even bits, fliping odd bits, flipping all bits, switching bits from right to left, and saving output to a file
switch (c)
{
case 'd': // debug
debug = 1;
break;
case 'e': // flip even bits
eflag = 1;
break;
case 'f': // flip odd bits
fflag = 1;
break;
case 'a': // flip all bits
aflag = 1;
break;
case 's': // switch bits right to left
sflag = 1;
break;
case 'o': // save output to file
oflag = 1;
fname = optarg;
break;
case '?':
err = 1;
break;
}
if ((optind + 1) > argc)
{
/* need at least one argument (change +1 to +2 for two, etc. as needeed) */
printf("optind = %d, argc=%d\n", optind, argc);
fprintf(stderr, "%s: missing intval\n", argv[0]);
fprintf(stderr, usage, argv[0]);
exit(1);
}
else if (err)
{
fprintf(stderr, usage, argv[0]);
exit(1);
}
if (optind < argc) /* these are the arguments after the command-line options */
for (; optind < argc; optind++)
{
inputCheck = atoi(argv[optind]); // converting argument string to int
userInput = inputCheck;
}
else
{
printf("No arguments left to process\n");
}
if (inputCheck > 65535)
{ // don't want numbers greater than largest 16bit -> 65535
printf("Please enter a number between 0 and 65535.\n");
exit(102);
}
// Code for switching even bits
if (eflag == 1)
{
uint16_t temp = userInput;
// for loop using every second bit starting at zero
for (int i = 0; i < 16; i += 2)
{
// setting bit at i
int bit = (temp >> i) & 1;
if (bit == 1)
{
// removing bit at i
temp = temp - (bit << i);
}
else
{
temp = temp + (1 << i); // adding 1 at i
}
}
eFlagResult = temp; // store temp in eFlagResult ready for output
}
// code for switching odd bits
if (fflag == 1)
{
uint16_t temp = userInput;
for (int i = 1; i < 16; i += 2)
{ // run loop for every second bit starting at bit 1
int bit = (temp >> i) & 1; // setting bit at i
if (bit == 1)
{
temp = temp - (bit << i); // removing bit at i
}
else
{
temp = temp + (1 << i); // adding 1 at i
}
}
fFlagResult = temp; // store temp in fFlagResult ready for output
}
if (aflag == 1)
{
uint16_t temp = ~(userInput); // flip bits using tilda
aFlagResult = temp; // store temp in aFlagResult ready for output
}
if (sflag == 1)
{
uint16_t temp = userInput;
int evenFlag = 0; // flag if temp is even
int distanceToOne = evenFirstOne(temp); // find how many 0's to the first 1
for (int i = 0; i <= INT_BITS; i++)
{ // loop through the bits starting at 0 and ending at INT_BITS
if (bit == 1)
{ // if bit is odd
bit = bit | (((temp >> i) & 0x1) << (INT_BITS - i)); // either keeping the bit or grabbing the bit from temp and shifting to INT_BITS - i in bit
}
else
{ // if bit is even
bit = bit | (((temp >> i) & 0x1) << (INT_BITS - i)); // either keeping the bit or grabbing the bit from temp and shifting to INT_BITS - i in bit
evenFlag = 1;
}
}
if (evenFlag == 1)
{ // add padding 0's
bit = bit << distanceToOne;
}
sFlagResult = bit; // store bit in sFlagResult ready for output
}
if (!oflag)
{
// if user chooses !oflag, output goes to stdout
printf("value: %u\n", userInput);
// Only print selected options
if (eflag == 1)
{
printf("Even bits flipped: %u\n", eFlagResult);
}
if (fflag == 1)
{
printf("Odd bits flipped: %u\n", fFlagResult);
}
if (aflag == 1)
{
printf("All bits flipped: %u\n", aFlagResult);
}
if (sflag == 1)
{
printf("Switched all bits: %d\n", sFlagResult);
}
}
else
{
fptr = fopen(fname, "w"); // Open fname (user entered) to write using a filepointer
if (fptr == NULL)
{ // something went wrong, print message and exit
printf("Unable to create oututfile \n");
exit(100);
}
fprintf(fptr, "%u %u %u %d", eFlagResult, fFlagResult, aFlagResult, sFlagResult); // print variables to file
fclose(fptr); // close file
printf("File successfully created\n"); // message to user
}
return (0);
}