How to use XOR to Encrypt a music file - iphone

I want to encrypt and decrypt 10000 bytes of a music file. I used the code :
if(file!=NULL && g!= NULL)
{
while(!feof(file))
{
count++;
char aByte;
fread(&aByte, sizeof(char), 1, file);
if (count <= 10000)
{
if (count % 2 == 0)
{
if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
}
else
{
if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
}
}
fwrite(&aByte, sizeof(char), 1, g);
}
}
fclose(file);
But the code does not work. Please help!!!

You shouldn't do the XOR when you're checking for EOF (which, by the way, fread indicates in its return value rather than in the value it writes to your buffer); only when you're preparing the byte to be written to the file.
Also, you'll need a much longer key if you want to encrypt it properly — and the key must be unknown to anyone who isn't supposed to be able to decrypt it.

Test your file handling by removing the "encryption". Take out these lines
if (count % 2 == 0)
{
if ((aByte ^ 'A') != EOF) aByte = aByte ^ 'A';
}
else
{
if ((aByte ^ 'B') != EOF) aByte = aByte ^ 'B';
}
Is your file the exact same? I think it will not be. Here are some reasons
The file is longer than 10,000 bytes -- you close file at the end, so I assume that those bytes are lost
The file is less than 10,000 bytes -- you don't check for EOF property, so it looks like an extra byte will be written
count is not initialized in this code -- if it's odd on one run and even on another, it wont' match. Also, it's just going to copy a random number of bytes depending on what count is. Perhaps it's initialized elsewhere.
You don't close g, so you can't be sure it was flushed (fwrite can buffer writes)
UPDATE: EOF is not a byte that you can find in a file, it's a special return value used by some FILE API functions (not fread).
The function getchar() is defined like this:
int getchar();
It either returns EOF or an int that is within the range of char. If it's EOF, then that means that you are at the end of the file. If not, you may safely cast the return to a char. The only stipulation on EOF is that it isn't a valid char. getchar() returns an int because it can return any char (256 choices) + EOF for a total of 257 choices which can't be represented in a char.
If you look at fread(), you will see that it doesn't have anything to do with chars. It takes a buffer, and record size, and a record count and returns the number of bytes read. You happen to be passing in sizeof(char) and 1 to get a char. It couldn't possibly store EOF in that char because EOF is not a valid char, it's an int and won't fit. It doesn't use the same conventions as getchar(). If it encounters EOF, it returns a number less than the total number of bytes requested. In your case, that's 0. If fread() returns 0, check feof() and ferror() to find out if you got to the end-of-file or got an error (both cause fread to return less than the number requested).

Related

Write a lex program that detects and counts the pattern that starts with an uppercase letter, ends with a lowercase letter

I understood the problem and written the below code. My code works and it prints the number of detected valid and invalid patterns when I quit the program with ctrl+z.
Here is my code:
%{
int valid = 0;
int invalid = 0;
%}
%%
([A-Z][a-zA-Z0-9]*[a-z])* {valid++;}
[a-zA-Z0-9]* {invalid++;}
%%
int yywrap(){}
int main(int argc, char **argv[])
{
printf("\n Enter inputs: \n\n");
yylex();
printf("\n\n\tNumber of VALID patterns = %d\n", valid);
printf("\tNumber of invalid patterns = %d\n\n", invalid);
return 0;
}
But I want something like this:
It should print the detected patterns, number of valid patterns and the number of invalid patterns whenever I input a new line.
There should be an EXIT command.
To achieve your goal, you should modify your code like this:
/*** Definition Section ***/
%{
int valid = 0;
int invalid = 0;
%}
/*** Rules Section ***/
%%
([A-Z][a-zA-Z0-9]*[a-z])* {printf("\n\tPattern Detected: %s ", yytext); valid++;}
[a-zA-Z0-9]* {invalid++;}
"\n" {
printf("\n\n\tNumber of VALID patterns = %d\n", valid);
printf("\tNumber of invalid patterns = %d\n\n", invalid);
valid = 0;
invalid = 0;
}
EXIT__ return 0;
%%
/*** User code section***/
int yywrap(){}
int main(int argc, char **argv[])
{
printf("\n Enter inputs: \n\n");
yylex();
return 0;
}
Here main change comes in the rule section.
Rule-1: ([A-Z][a-zA-Z0-9]*[a-z])* It detect and count valid patterns that starts with an uppercase letter, ends with a lowercase letter. In action, it prints the detected patterns and does the counting job too. Here yytext contains the text in the buffer, for this rule, it's the detected pattern.
Rule-2: [a-zA-Z0-9]* Keep a track of invalid patterns. It will help to prevent returning unmatched patterns.
Rule-3: "\n" It detects when you input a new line. In action, it prints the detected patterns, the number of valid patterns, and the number of invalid patterns whenever I input a new line. Also, reset the variables for counting to zero for the next line of input.
Rule-4: EXIT__ whenever you will input this exact command, the program will exit.
You can avoid printing the numbers of valid and invalid patterns inside the main function in the user code section.
But if you want to print the numbers of detected valid and invalid patterns at the end too, then this program will require a few modifications.

Iterate through alphabet in Swift explanation

I accidentally wrote this simple code to print alphabet in terminal:
var alpha:Int = 97
while (alpha <= 122) {
write(1, &alpha, 1)
alpha += 1
}
write(1, "\n", 1)
//I'm using write() function from C, to avoid newline on each symbol
And I've got this output:
abcdefghijklmnopqrstuvwxyz
Program ended with exit code: 0
So, here is the question: Why does it work?
In my logic, it should display a row of numbers, because an integer variable is being used. In C, it would be a char variable, so we would mean that we point to a sign at some index in ASCII. Then:
char alpha = 97;
Would be a code point to an 'a' sign, by incrementing alpha variable in a loop we would display each element of ascii through 122nd.
In Swift though, I couldn't assign an integer to Character or String type variable. I used Integer and then declared several variables to assign UnicodeScalar, but accidentally I found out that when I'm calling write, I point to my integer, not the new variable of UnicodeScalar type, although it works! Code is very short and readable, but I don't completely understand how does work and why at all.
Has anyone had such situation?
Why does it work?
This works “by chance” because the integer is stored in little-endian byte order.
The integer 97 is stored in memory as 8 bytes
0x61 0x00 0x00 0x00 0x00 0x00 0x00 0x00
and in write(1, &alpha, 1), the address of that memory location is
passed to the write system call. Since the last parameter (nbyte)
is 1, the first byte at that memory address is written to the
standard output: That is 0x61 or 97, the ASCII code of the letter
a.
In Swift though, I couldn't assign an integer to Character or String type variable.
The Swift equivalent of char is CChar, a type alias for Int8:
var alpha: CChar = 97
Here is a solution which does not rely on the memory layout and
works for non-ASCII character as well:
let first: UnicodeScalar = "α"
let last: UnicodeScalar = "ω"
for v in first.value...last.value {
if let c = UnicodeScalar(v) {
print(c, terminator: "")
}
}
print()
// αβγδεζηθικλμνξοπρςστυφχψω

Matching Unicode punctuation using LPeg

I am trying to create an LPeg pattern that would match any Unicode punctuation inside UTF-8 encoded input. I came up with the following marriage of Selene Unicode and LPeg:
local unicode = require("unicode")
local lpeg = require("lpeg")
local punctuation = lpeg.Cmt(lpeg.Cs(any * any^-3), function(s,i,a)
local match = unicode.utf8.match(a, "^%p")
if match == nil
return false
else
return i+#match
end
end)
This appears to work, but it will miss punctuation characters that are a combination of several Unicode codepoints (if such characters exist), as I am reading only 4 bytes ahead, it probably kills the performance of the parser, and it is undefined what the library match function will do, when I feed it a string that contains a runt UTF-8 character (although it appears to work now).
I would like to know whether this is a correct approach or if there is a better way to achieve what I am trying to achieve.
The correct way to match UTF-8 characters is shown in an example in the LPeg homepage. The first byte of a UTF-8 character determines how many more bytes are a part of it:
local cont = lpeg.R("\128\191") -- continuation byte
local utf8 = lpeg.R("\0\127")
+ lpeg.R("\194\223") * cont
+ lpeg.R("\224\239") * cont * cont
+ lpeg.R("\240\244") * cont * cont * cont
Building on this utf8 pattern we can use lpeg.Cmt and the Selene Unicode match function kind of like you proposed:
local punctuation = lpeg.Cmt(lpeg.C(utf8), function (s, i, c)
if unicode.utf8.match(c, "%p") then
return i
end
end)
Note that we return i, this is in accordance with what Cmt expects:
The given function gets as arguments the entire subject, the current position (after the match of patt), plus any capture values produced by patt. The first value returned by function defines how the match happens. If the call returns a number, the match succeeds and the returned number becomes the new current position.
This means we should return the same number the function receives, that is the position immediately after the UTF-8 character.

perl bitwise AND and bitwise shifting

I was reading some example code snippet for the module Net::Pcap::Easy, and I came across this piece of code
my $l3protlen = ord substr $raw_bytes, 14, 1;
my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part
return unless $l3prot == 4; # return unless IPv4
my $l4prot = ord substr $packet, 23, 1;
return unless $l4prot == '7';
After doing a total hex dump of the raw packet $raw_bytes, I can see that this is an ethernet frame, and not on a TCP/UDP packet. Can someone please explain what the above code does?
For parsing the frame, I looked up this page.
Now onto the Perl...
my $l3protlen = ord substr $raw_bytes, 14, 1;
Extract the 15th byte (character) from $raw_bytes, and convert to its ordinal value (e.g. a character 'A' would be converted to an integer 65 (0x41), assuming the character set is ASCII). This is how Perl can handle binary data as if it were a string (e.g. passing it to substr) but then let you get the binary values back out and handle them as numbers. (But remember TMTOWTDI.)
In the IPv4 frame, the first 14 bytes are the MAC header (6 bytes each for destination and source MAC address, followed by 2-byte Ethertype which was probably 0x8000 - you could have checked this). Following this, the 15th byte is the start of the Ethernet data payload: the first byte of this contains Version (upper 4 bytes) and Header Length in DWORDs (lower 4 bytes).
Now it looks to me like there is a bug in the next line of this sample code, but it may well normally work by a fluke!
my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part
In Perl, >> has higher precedence than &, so this will be equivalent to
my $l3prot = $l3protlen & (0xf0 >> 2);
or if you prefer
my $l3prot = $l3protlen & 0x3c;
So this extracts bits 2 - 5 from the $l3prot value: the mask value 0x3c is 0011 1100 in binary. So for example a value of 0x86 (in binary, 1000 0110) would become 0x04 (binary 0000 0100).
In fact a 'normal' IPv4 value is 0x45, i.e. protocol type 4, header length 5 dwords. Mask that with 0x3c and you get... 4! But only by fluke: you have tested the top 2 bits of the length, not the protocol type!
This line should surely be
my $l3prot = ($l3protlen & 0xf0) >> 4;
(note brackets for precedence and a shift of 4 bits, not 2). (I found this same mistake in the CPAN documentation so I guess it's probably quite widely spread.)
return unless $l3prot == 4; # return unless IPv4
For IPv4 we expect this value to be 4 - if it isn't, jump out of the function right away. (So the wrong code above gives the result which lets this be interpreted as an IPv4 packet, but only by luck.)
my $l4prot = ord substr $packet, 23, 1;
Now extract the 24th byte and convert to ordinal value in the same way. This is the Protocol byte from the IP header:
return unless $l4prot == '7';
We expect this to be 7 - if it isn't jump out of the function right away. (According to IANA, 7 is "Core-based trees"... but I guess you know which protocols you are interested in!)

How does Perl store integers in-memory?

say pack "A*", "asdf"; # Prints "asdf"
say pack "s", 0x41 * 256 + 0x42; # Prints "BA" (0x41 = 'A', 0x42 = 'B')
The first line makes sense: you're taking an ASCII encoded string, packing it into a string as an ASCII string. In the second line, the packed form is "\x42\x41" because of the little endian-ness of short integers on my machine.
However, I can't shake the feeling that somehow, I should be able to treat the packed string from the second line as a number, since that's how (I assume) Perl stores numbers, as little-endian sequence of bytes. Is there a way to do so without unpacking it? I'm trying to get the correct mental model for the thing that pack() returns.
For instance, in C, I can do this:
#include <stdio.h>
int main(void) {
char c[2];
short * x = c;
c[0] = 0x42;
c[1] = 0x41;
printf("%d\n", *x); // Prints 16706 == 0x41 * 256 + 0x42
return 0;
}
If you're really interested in how Perl stores data internally, I'd recommend PerlGuts Illustrated. But usually, you don't have to care about stuff like that because Perl doesn't give you access to such low-level details. These internals are only important if you're writing XS extensions in C.
If you want to "cast" a two-byte string to a C short, you can use the unpack function like this:
$ perl -le 'print unpack("s", "BA")'
16706
However, I can't shake the feeling that somehow, I should be able to treat the packed string from the second line as a number,
You need to unpack it first.
To be able to use it as a number in C, you need
char* packed = "\x42\x41";
int16_t int16;
memcpy(&int16, packed, sizeof(int16_t));
To be able to use it as a number in Perl, you need
my $packed = "\x42\x41";
my $num = unpack('s', $packed);
which is basically
use Inline C => <<'__EOI__';
SV* unpack_s(SV* sv) {
STRLEN len;
char* buf;
int16_t int16;
SvGETMAGIC(sv);
buf = SvPVbyte(sv, len);
if (len != sizeof(int16_t))
croak("usage");
Copy(buf, &int16, 1, int16_t);
return newSViv(int16);
}
__EOI__
my $packed = "\x42\x41";
my $num = unpack_s($packed);
since that's how (I assume) perl stores numbers, as little-endian sequence of bytes.
Perl stores numbers in one of following three fields of a scalar:
IV, a signed integer of size perl -V:ivsize (in bytes).
UV, an unsigned integer of size perl -V:uvsize (in bytes). (ivsize=uvsize)
NV, a floating point numbers of size perl -V:nvsize (in bytes).
In all case, native endianness is used.
I'm trying to get the correct mental model for the thing that pack() returns.
pack is used to construct "binary data" for interfacing with external APIs.
I see pack as a serialization function. It takes as input Perl values, and outputs a serialized form. The fact the output serialized form happens to be a Perl bytestring is more of an implementation detail than a core functionality.
As such, all you're really expected to do with the resulting string is feed it to unpack, though the serialized form is convenient to have it move around processes, hosts, planets.
If you're interested in serializing it to a number instead, consider using vec:
say vec "BA", 0, 16; # prints 16961
To take a closer look at the string's internal representation, take a look at Devel::Peek, though you're not going to see anything surprising with a pure ASCII string.
use Devel::Peek;
Dump "BA";
SV = PV(0xb42f80) at 0xb56300
REFCNT = 1
FLAGS = (POK,READONLY,pPOK)
PV = 0xb60cc0 "BA"\0
CUR = 2
LEN = 16