need hint with a custom Linux/UNIX command line utlity "cal" in C - c

Ok I need to make this program to display "cal" 3 month(one month before and one month after) side by side, rather than just one single month it displays in any Linux/UNIX. I got it working to display 3 calendar by using "system(customCommand)" three times; but then it's not side by side.
I got some hint to use the following system calls:
close(..) pipe(..) dup2(..) read(..) and write(..)
my question is what should I start with? Do I need to create child process and than catch it in pipe(..)?
How can I display three calendar side by side.
ex.
February 2009 March 2009 April 2009
S M Tu W Th F S S M Tu W Th F S S M Tu W Th F S
1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4
8 9 10 11 12 13 14 8 9 10 11 12 13 14 5 6 7 8 9 10 11
15 16 17 18 19 20 21 15 16 17 18 19 20 21 12 13 14 15 16 17 18
22 23 24 25 26 27 28 22 23 24 25 26 27 28 19 20 21 22 23 24 25
29 30 31 26 27 28 29 30

Assuming you want to write it yourself instead of using "cal -3", what I'd do (in psuedo code):
popen three calls to "cal" with the appropriate args
while (at least one of the three pipes hasn't hit EOF yet)
{
read a line from the first if it isn't at EOF
pad the results out to a width W, print it
read a line from the second if it isn't at EOF
pad the results out to a width W, print it
read a line from the third if it isn't at EOF
print it
print "\n"
}
pclose all three.

if "cal -3" doesn't work, just use paste :)
$ TERM=linux setterm -regtabs 24
$ paste <(cal 2 2009) <(cal 3 2009) <(cal 4 2009)
febbraio 2009 marzo 2009 aprile 2009
do lu ma me gi ve sa do lu ma me gi ve sa do lu ma me gi ve sa
1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4
8 9 10 11 12 13 14 8 9 10 11 12 13 14 5 6 7 8 9 10 11
15 16 17 18 19 20 21 15 16 17 18 19 20 21 12 13 14 15 16 17 18
22 23 24 25 26 27 28 22 23 24 25 26 27 28 19 20 21 22 23 24 25
29 30 31 26 27 28 29 30
$
(setterm ignores -regtabs unless TERM=linux or TERM=con.)

just do
cal -3

Does this not work?
cal -3

Ok, how about cal -3?
cal -3 12 2120 to make it a special month and year, with one before and one after.

The approach I would use for this would be to capture the output, split it into lines, and printf the lines out next to each other. I'd probably do it in Perl, though, rather than C.
Or just use cal -3, if your cal has it.

Related

A problem with fscanf() in c , overwriting other variables

I'm traying to read from a file two things :
1- a list of integers(on the top of the file) in to an array of integers inputs[]
2- 3 matrixes 5x5 etch into an array of array of array boards[][][]
the firs part works properly but when the 2 part finished some how the inputs[] change values
The code :
void loadfile(const char* filepath,int *inputs ,int boards [nboards][size][size]){
FILE *inp=fopen(filepath,"r");
//loading the marked numbers
for(int i=0;i<4;i++){
fscanf(inp,"%d",inputs+i);
//to show that inputs reseve the the right values at the start
printf("%d ",*(inputs+i));
fseek(inp,ftell(inp)+1,SEEK_SET);
}
printf("\n");
//loaing the boards
for(int n=1;n<=nboards;n++){
for(int i=0;i<size;i++)
for(int j=0;j<size;j++){
fscanf(inp,"%d",&boards[n][i][j]);
printf("%d ",boards[n][i][j]);
}
printf("\n");
}
fclose(inp);
}
int main(){
int inputs[4]={};
int boards[nboards][size][size]={};
loadfile("inputs.txt",inputs,boards);
for(int i=0;i<4;i++)
printf("%d ",*(inputs+i));
}
The file :
7,4,9,5
22 13 17 11 0
8 2 23 4 24
21 9 14 16 7
6 10 3 18 5
1 12 20 15 19
3 15 0 2 22
9 18 13 17 5
19 8 7 25 23
20 11 10 24 4
14 21 16 12 6
14 21 17 24 4
10 16 15 9 19
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7
The output:
7 4 9 5
22 13 17 11 0 8 2 23 4 24 21 9 14 16 7 6 10 3 18 5 1 12 20 15 19
3 15 0 2 22 9 18 13 17 5 19 8 7 25 23 20 11 10 24 4 14 21 16 12 6
14 21 17 24 4 10 16 15 9 19 18 8 23 26 20 22 11 13 6 5 2 0 12 3 7
21 17 24 4

How do I perform shell sort using sequence {3,2,1}?

Suppose I have an array:
30 20 29 19 28 18 27 17 26 16 25 15 24 14 23 13 22 12 21 11
I am not understanding how to do the shell sort using sequence 3:
Would I simply do this:
30 20 29 19 28 18 27 17 | 26 16 25 15 24 14 |23 13 22 12 21 11
Where I split it into 3 parts and sort the respective parts? And then do the same with 2 sorting after, except split into halves? What is the right way to do this? Can someone please explain?
If you look at your array and number the locations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
30 20 29 19 28 18 27 17 26 16 25 15 24 14 23 13 22 12 21 11
In a shell sort, what you do is start with a skip number (in your case 3) so to make the first "list" you take a number and skip. With 3 this would be 1st, 4th, 7th etc.
So you would have a list of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
30 19 27 16 24 13 21
and a second list of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
20 28 17 25 14 22 11
The 3rd list is the remaining items.
For the next round you do it with one less... so items at odd number locations and items at even number locations.
In response to comment below
A Shell sort is an in-place sort — that means you don't remove the items to new lists or create any new data structures. You are using the array to "treat" items which are "far apart" in terms of array locations as next to each other. You don't actually make new lists or new arrays (that is why I showed my diagrams as I did); you just look at these locations.
Why?
Because it means that when you start (for example with 3) you are moving stuff farther) -- eg the 13 that starts at location 16 gets moved to location 1 in the first pass. Then as you reduce the number you start doing more local changes. This means you gain an advantage over a typical bubble sort. Still not good — but MUCH better than a bubble sort.

Create matrix of some repeating numbers

EN = 10;
etable = [1,2,3,4,5,6;
4,5,6,7,8,9;
7,8,9,10,11,12;
10,11,12,13,14,15;
13,14,15,16,17,18;
16,17,18,19,20,21;
19,20,21,22,23,24;
22,23,24,25,26,27;
25,26,27,28,29,30;
28,29,30,31,32,33];
Is it possible to make a for loop in which I just change the EN value and it automatically creates etable? Because I have to make EN 50 so it'll not be good to write 50 lines in etable.
I tried in this way:
EN = 10;
c = 1:EN;
nodes = zeros(size(c',1),2);
for i = 1:length(c)
nodes(i,1) = i;
nodes(i,2) = i+1;
end
etable = zeros(size(c',1),6);
for i = 1:size(nodes,1)
etable(i,1) = 2*nodes(i,1)-1;
etable(i,2) = 2*nodes(i,1);
etable(i,3) = 2*nodes(i,1)+1;
etable(i,4) = 2*nodes(i,2);
etable(i,5) = 2*nodes(i,2)+1;
etable(i,6) = 2*nodes(i,2)+2;
end
You can use implicit expansion implicitly (introduced in MATLAB R2016b) or explicitly by using MATLAB's bsxfun to create that matrix:
% Parameters
EN = 10;
n = 6;
step = 3;
% Matrix (implict expansion, MATLAB >= R2016b)
etable = (0:step:EN*step-1).' + (1:n)
% Matrix (bsxfun, MATLAB < R2016b)
etable_legacy = bsxfun(#plus, (0:step:EN*step-1).', (1:n))
For the given parameter set, the outputs are:
etable =
1 2 3 4 5 6
4 5 6 7 8 9
7 8 9 10 11 12
10 11 12 13 14 15
13 14 15 16 17 18
16 17 18 19 20 21
19 20 21 22 23 24
22 23 24 25 26 27
25 26 27 28 29 30
28 29 30 31 32 33
etable_legacy =
1 2 3 4 5 6
4 5 6 7 8 9
7 8 9 10 11 12
10 11 12 13 14 15
13 14 15 16 17 18
16 17 18 19 20 21
19 20 21 22 23 24
22 23 24 25 26 27
25 26 27 28 29 30
28 29 30 31 32 33
You can change EN (number of rows), the "number of columns" n and/or the "step between rows" step.
Hope that helps.

Matlab: repeat and concatenate rows and cols into new array

I have two 4-by-4 arrays:
a1 = [ 1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16 ]
a2 = [ 17 18 19 20; 21 22 23 24; 25 26 27 28; 29 30 31 32 ]
I need to create 16-by-8 array C:
1 2 3 4 17 18 19 20
1 2 3 4 21 22 23 24
1 2 3 4 25 26 27 28
1 2 3 4 29 30 31 32
5 6 7 8 17 18 19 20
5 6 7 8 21 22 23 24
5 6 7 8 25 26 27 28
5 6 7 8 29 30 31 32
9 10 11 12 17 18 19 20
9 10 11 12 21 22 23 24
9 10 11 12 25 26 27 28
9 10 11 12 29 30 31 32
13 14 15 16 17 18 19 20
13 14 15 16 21 22 23 24
13 14 15 16 25 26 27 28
13 14 15 16 29 30 31 32
The left half (from 1st to 4th column) of the result array C should repeat 4 times i-th row of the array a1, the right half (from 5th to 8th column) should repeat 4 times the array a2.
Below is my code.
p=4
n=4
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=1:p
for k=a:b
C(k,j)=a1(i,j);
end;
end;
end;
for i=1:n
b=n*i;
a=n*(i-1)+1;
for j=p+1:2*p
l=1;
for k=a:b
C(k,j)=a2(l,j-p);
l=l+1;
end;
end;
end;
C;
size_C=size(C)
Question. Is it possible to create result array C without for-loop? Which functions can I use?
Yes it's possible.
One way of doing it is by using kron and repmat
C = [ kron(a1, ones(4,1)) repmat(a2, 4, 1)]
Perhaps the 4 should be derived from the size of one of the matrixes
You can use ndgrid to generate the row indices and then concatenate:
[ii, jj] = ndgrid(1:size(a2,1), 1:size(a1,1));
C = [a1(jj,:) a2(ii,:)];
With focus on performance, here's one using reshape and repmat -
% Store sizes
M = size(a1,1);
N = size(a2,1);
% Get the replicated version for a1 and a2 separately
parte1 = reshape(repmat(reshape(a1,1,M,[]),[N,1,1]),M*N,[])
parte2 = repmat(a2,[M,1]);
% Do columnar concatenatation for final output
out = [parte1 parte2]
Sample run on a generic case -
a1 = % 3 x 4 array
5 2 6 9
7 4 7 6
9 8 6 1
a2 = % 2 x 5 array
7 7 1 9 2
6 8 8 7 9
out =
5 2 6 9 7 7 1 9 2
5 2 6 9 6 8 8 7 9
7 4 7 6 7 7 1 9 2
7 4 7 6 6 8 8 7 9
9 8 6 1 7 7 1 9 2
9 8 6 1 6 8 8 7 9

XOR File Decryption

So I have to decrypt a .txt file that is crypted with XOR code and with a repeated password that is unknown, and the goal is to discover the message.
Here are the things that I already know because of the professor:
First I need to find the length of the unknown password
The message has been altered and it doesn't have spaces (this may add a bit more difficulty because the space character has the highest frequency in a message)
Any ideas on how to solve this?
thx in advanced :)
First you need to find out the length of the password. You do this by assessing the Index of Coincidence or Kappa-test. XOR the ciphertext with itself shifted 1 step and count the number of characters that are the same (value 0). You get the Kappa value by dividing the result with the total number of characters minus 1. Shift one more time and again calculate the Kappa value. Shift the ciphertext as many times as needed until you discover the password length. If the length is 4 you should see something similar to this:
Offset Hits
-------------------------
1 2.68695%
2 2.36399%
3 3.79009%
4 6.74012%
5 3.6953%
6 1.81582%
7 3.82744%
8 6.03504%
9 3.60273%
10 1.98052%
11 3.83241%
12 6.5627%
As you see the Kappa value is significantly higher on multiples of 4 (4, 8 and 12) than the others. This suggests that the length of the password is 4.
Now that you have the password length you should again XOR the cipher text with itself but now you shift by multiples of the length. Why? Since the ciphertext looks like this:
THISISTHEPLAINTEXT <- Plaintext
PASSPASSPASSPASSPA <- Password
------------------
EJKELDOSOSKDOWQLAG <- Ciphertext
When two values which are the same are XOR:ed the result is 0:
EJKELDOSOSKDOWQLAG <- Ciphertext
EJKELDOSOSKDOWQLAG <- Ciphertext shifted 4.
Is in reality:
THISISTHEPLAINTEXT <- Plaintext
PASSPASSPASSPASSPA <- Password
THISISTHEPLAINTEXT <- Plaintext
PASSPASSPASSPASSPA <- Password
Which is:
THISISTHEPLAINTEXT <- Plaintext
THISISTHEPLAINTEXT <- Plaintext
As you see the password "disappears" and the plaintext is XOR:ed with itself.
So what can we do now then? You wrote that the spaces are removed. This makes it a bit harder to get the plaintext or password. But not at all impossible.
The following table shows the ciphertext values for all english characters:
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
A 0
B 3 0
C 2 1 0
D 5 6 7 0
E 4 7 6 1 0
F 7 4 5 2 3 0
G 6 5 4 3 2 1 0
H 9 10 11 12 13 14 15 0
I 8 11 10 13 12 15 14 1 0
J 11 8 9 14 15 12 13 2 3 0
K 10 9 8 15 14 13 12 3 2 1 0
L 13 14 15 8 9 10 11 4 5 6 7 0
M 12 15 14 9 8 11 10 5 4 7 6 1 0
N 15 12 13 10 11 8 9 6 7 4 5 2 3 0
O 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
P 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0
Q 16 19 18 21 20 23 22 25 24 27 26 29 28 31 30 1 0
R 19 16 17 22 23 20 21 26 27 24 25 30 31 28 29 2 3 0
S 18 17 16 23 22 21 20 27 26 25 24 31 30 29 28 3 2 1 0
T 21 22 23 16 17 18 19 28 29 30 31 24 25 26 27 4 5 6 7 0
U 20 23 22 17 16 19 18 29 28 31 30 25 24 27 26 5 4 7 6 1 0
V 23 20 21 18 19 16 17 30 31 28 29 26 27 24 25 6 7 4 5 2 3 0
W 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 7 6 5 4 3 2 1 0
X 25 26 27 28 29 30 31 16 17 18 19 20 21 22 23 8 9 10 11 12 13 14 15 0
Y 24 27 26 29 28 31 30 17 16 19 18 21 20 23 22 9 8 11 10 13 12 15 14 1 0
Z 27 24 25 30 31 28 29 18 19 16 17 22 23 20 21 10 11 8 9 14 15 12 13 2 3 0
What does this mean then? If an A and a B is XOR:ed then the resulting value is 3. E and P will result in 21. Etc. OK but how will this help you?
Remember that the plaintext is XOR:ed with itself shifted by multiples of the password length. For each value you can check the above table and determine what combinations that position could have. Lets say the value is 25 then the two characters that resulted in the value 25 could be one of the following combinations:(I-P), (H-Q), (K-R), (J-S), (M-T), (L-U), (O-V), (N-W), (A-X) or (C-Z). But which one? Now you do more shifts and look up the corresponding values in the table again for each position. Next time the value might be 7 and since you already have a list of possible character combinations you only check against them. At the next two shifts the values are 3 and 1. Now you can determine that the character is W since that is the only common character in each shift, (N-W), (P-W), (T-W), (V-W). You can do this for most positions.
You will not get all the plaintext but you will get enough characters to discover the password. Take the known characters and XOR them in the correct position in the ciphertext. This will yield the password. The number of known characters you need atleast is the number of characters in the password if they are at the "correct" positions in regards to the password.
Good luck!
you should look at cracking a vigenere chiffre, especially at auto-correlation. The latter will help you finding out the length of the password and the rest is usually just bruteforcing on the normal distribution of letters (where the most common one is the letter e in the english language).
Although spaces are the most common characters and make decryptions like this easy, the other character also have different frequencies. For example, see this Wikipedia article. If you've got enough encrypted text and the password length isn't too large, it might just be enough to find out the most common bytes in the encrypted text. They will most likely be the encrypted versions of e that has the highest frequency in english texts.
This alone won't give you the decrypted text, but it's very likely you can find out the password length and (part of) the password itself with it. For example, let's assume the most frequent encrypted bytes are
w x m z y
with almost the same frequency and there's a significant drop in frequency after the last one. This will tell you two things:
The password length most likely is 5, because statistically, all encrypted e will be equally likely. EDIT: OK, this isn't correct, it will be 5 or above because the password can contain the same character multiple times.
The password will be some permutation of (w x m z y XOR e e e e e) - you can use the byte offsets modulo the password length to get the correct permutation.
EDIT: The same character occuring in the password multiple times makes things a bit harder, but you'll most likely be able to identify those because as I said, encrypted versions of e will cluster around frequency f - now if the character occurs n times, it will have a frequency near n*f.
The most common three letter trigram in English (assuming the language is probably English) is "the". Place "the" at all possible points on your cyphertext to derive a possible 3 characters of the key. Try each possible key fragment at all other possible positions on the cyphertext and see what you get. For example, "qzg" is unlikely to be correct, but "fen" could be. Look at the spacing between possible positions to derive the key length. With a key length and a key fragment you can place a lot more of the key.
As Lars said, look at ways of decrypting Vigenère, which is effectively what you have here.

Resources