I am using the euclidean algorithm when i have p = 163, q = 311 and e = 281. Here is what i have so far
N = p * q = 50693
Totient Symbol(n) = 162 x 310 = 50220
1. 50220 = 178(281) + 202
2. 281 = 1 (202) + 79
3. 202 = 2 (79) + 44
4. 79 = 1 (44) + 35
5. 44 = 1 (35) + 9
6. 35 = 3 (9) + 8
7. 9 = 1 (8) + 1
8. 8 = 8 (1) + 0
I then move on to back substitution
A. 9 = 1 (8) + 1 === 1 = 9-1(8)
B. 8 = 35 – 3(9)
C. 1 = 1(9)-1(35-3(9)) -
D. 1 = 3(9) – 1(35) + 1(9) add similar items
E. 1 = 4(9) -1(35)
9 = 44 – 1(35)
1 = 4 (44-1(35)) – 1(35)
1 = 4(44)-4(35)-1(35)
1 = 4(44) – 5(35)
Take value next to 35 (5), subtract it from totient
50220 – 5 = 50215
d = 50215
This is wrong as i used an online calc to verify . Can anyone point me in the right direction here, i think the back substituion is wrong
There are two different ways to calculate RSA d values, the φ (phi / totient) method, and the λ (lambda / least common multiple) method. While the original RSA paper (and RFC 2313) use phi, modern implementations (and RFC 2437) use lambda.
The totient value is easy: (p-1)(q-1) = 50220.
For lambda(p-1, q-1) we need to first compute GCD(p-1, q-1), the example uses the subtraction form of the Euclidian algorithm:
GCD(162, 310)
GCD(162, 148)
GCD(14, 148)
GCD(14, 134)
GCD(14, 120)
GCD(14, 106)
GCD(14, 92)
GCD(14, 78)
GCD(14, 64)
GCD(14, 50)
GCD(14, 36)
GCD(14, 22)
GCD(14, 8)
GCD(6, 8)
GCD(6, 2)
GCD(4, 2)
GCD(2, 2)
GCD = 2
The least common multiple of (a, b) is a * b / GCD(a, b). So the lambda value is the totient / GCD, or 25110.
Now, to compute dPhi = ModInv(e, phi) or dLambda = ModInv(e, lambda) we can use the Extended Euclidean Algorithm:
ModInverse(281, 50220)
r=50220, newR=281, t= 0, newT= 1
r= 281, newR=202, t= 1, newT= -178
r= 202, newR= 79, t= -178, newT= 179
r= 79, newR= 44, t= 179, newT= -536
r= 44, newR= 35, t= -536, newT= 715
r= 35, newR= 9, t= 715, newT=-1251
r= 9, newR= 8, t=-1251, newT= 4468
r= 8, newR= 1, t= 4468, newT=-5719
r= 1, newR= 0, t=-5719, newT=50220
Correcting the sign of t
dPhi = 44501
ModInverse(281, 25110)
r=25110, newR=281, t= 0, newT= 1
r= 281, newR=101, t= 1, newT= -89
r= 101, newR= 79, t= -89, newT= 179
r= 79, newR= 22, t= 179, newT= -268
r= 22, newR= 13, t= -268, newT= 983
r= 13, newR= 9, t= 983, newT=-1251
r= 9, newR= 4, t=-1251, newT= 2234
r= 4, newR= 1, t= 2234, newT=-5719
r= 1, newR= 0, t=-5719, newT=25110
Correcting the sign of t
dLambda = 19391
You seem to have done the descending step of the Extended Euclidean Algorithm correctly, but being unfamiliar with the back-propogation calculation (as opposed to the inline form) I don't see where you made a value or arithmetic error.
Related
histcounts(1:100,'BinWidth',50)
returns
49 51
Why doesn't it return
50 50
instead?
Histogramming 1 to 100 inclusive with h = histogram(1:100, 'BinWidth', 50) gives:
Let's see the bin edges:
h.BinEdges
ans =
0 50 100
From MATLAB's help:
Each bin includes the left edge, but does not include the right edge,
except for the last bin which includes both edges
That means that values 1 to 100 are histogrammed in this format:
Bin 1 => edges: [0 50) => Included values: [1, 2, 3, .., 49] (n = 49)
Bin 2 => edges: [50 100] => Included values: [50, 51, 52, .., 100] (n = 51)
histcount(X) partitions X in the same manner as histogram(X). Therefore, the results are what you should expect and in fact very reasonable.
I have 2 arrays (vectors? in m vernacular?) and I want to sort them in unison. How can I achieve this in Matlab?
For example; I have found the peaks from a histogram and they are stored in 2 arrays; peakXVals, peakYVals. They will always be arranged in ascending x axis index. So they will always look like:
peakXVals = [0, 3, 20, 77, 240];
peakYVals = [10, 999, 30, 40, 20];
I wish to sort both arrays based of the values in peakYVals in descending order. Ie from largest peak to smallest peak. So the desired result is:
peakXVals = [3, 77, 20, 240, 0];
peakYVals = [999, 40, 30, 20, 10];
What function's can I use to achieve this in Matlab?
Use sort:
peakXVals = [0, 3, 20, 77, 240];
peakYVals = [10, 999, 30, 40, 20];
>> [B,I] = sort(peakYVals, 'descend')
B =
999 40 30 20 10
I =
2 4 3 5 1
Then:
>> peakXVals_sorted = peakXVals(I)
peakXVals_sorted =
3 77 20 240 0
>> peakYVals_sorted = B
peakYVals_sorted =
999 40 30 20 10
You can arrange the two vectors as columns of a matrix and sort the rows of that matrix as atoms, in lexicographical order. Then the results are the columns of the sorted matrix:
tmp = sortrows([peakYVals(:) peakXVals(:)], 'descend');
peakYVals = tmp(:,1).';
peakXVals = tmp(:,2).';
I am writing a MATLAB function playing a song (Game of Thrones theme).
I have the correct keystroke and duration. I am trying to have two (treble and bass) playing at once and for each keystroke to be the correct duration. For some reason, I cannot get the duration to work with the keystroke (they all are playing at duration=1) or for the two sets to play together. Any ideas?
function xx = key2note(X, keynum, dur)
% KEY2NOTE Produce a sinusoidal waveform corresponding to a given piano key number
% usage: xx = key2note (X, keynum, dur)
% xx = the output sinusoidal waveform
% X = complex amplitude for the sinusoid, X = A*exp(j*phi).
% keynum = the piano keyboard number of the desired note
% dur = the duration (in seconds) of the output note
fs = 8000;
tt = (1/fs):(1/fs):dur;
freq = 440*(2^((keynum-49)/12)); %<=============== fill in this line
xx = real(X*exp(j*2*pi*freq*tt)); %<=============== fill in this line
end
t = 0.17;
%treble - 40 is middle C
throne.keys = [47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47, 40, 40 45 47, 40 43 45, 42 47 36 40];
throne.dur = [ 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 4, 4, 1 1 2 1, 2 1 1, 1 1 1 1];
%bass
throne.keys2 = [ 21, 21 25 28 31 28 25, 21 25 28 31 28 25];
throne.dur2 = [ 32, 1/3 1/3 1/3 1/3 1/3 1/3, 1/3 1/3 1/3 1/3 1/3 1/3];
throne.durations = 0.2 * ones(1,length(throne.dur));
fs = 8000; % 11025 Hz also works
f = 329.62;
xx = zeros(1, sum(throne.dur)*fs + length(throne.keys));
n1 = 1;
for kk = 1:length(throne.keys)
keynum = throne.keys(kk);
tone = key2note(1,keynum,0.25); %amplitude 1, keynum, 0.38s % <------- Fill in this line
n2 = n1 + length(tone) - 1;
xx(n1:n2) = tone; %<------- Insert the note
n1 = n2 + 1;
end
fs = 8000;
%xt = zeros(1, sum(tdur)*fs + length(keyst));
%xb = zeros(1, sum(bdur)*fs + 1);
%xa = zeros(1, sum(adur)*fs+1);
%xd = zeros(1, sum(ddur)*fs+1);
%xx = xt + xb + xa + xd
xx = xt + xb;
soundsc(xx,fs)
I commented some never used lines out - you might want to uncomment them if they were used for something else later. Also I felt so free as to make t a global speed control.
t = 0.17; % this variable was never used.
%I assumed you wanted to control the overall speed with it and felt so free to adjust the durations with it.
%treble - 40 is middle C
throne.keys = [47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47, 40, 40 45 47, 40 43 45, 42 47 36 40];
throne.dur = t*[ 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 4, 4, 1 1 2 1, 2 1 1, 1 1 1 1];
%bass
throne.keys2 = [ 21, 21 25 28 31 28 25, 21 25 28 31 28 25];
throne.dur2 = t*[ 32, 1/3 1/3 1/3 1/3 1/3 1/3, 1/3 1/3 1/3 1/3 1/3 1/3];
%throne.durations = 0.2 * ones(1,length(throne.dur)); % this was never used - no clue what you intended to do with it
fs = 8000; % 11025 Hz also works
%f = 329.62; % is also never used
%treble loop
xt = zeros(1, ceil(sum(throne.dur)*fs + length(throne.keys)));
n1 = 1;
for kk = 1:length(throne.keys)
tone = key2note(1,throne.keys(kk),throne.dur(kk)); % You used here the constant length of 0.25 instead of taking the duration value from throne.dur
n2 = n1 + length(tone) - 1;
xt(n1:n2) = tone; %<------- Insert the note
n1 = n2 + 1;
end
%Bass loop
xb = zeros(1, ceil(sum(throne.dur2)*fs + length(throne.keys2)));
n1 = 1;
for kk = 1:length(throne.keys2)
tone2 = key2note(1,throne.keys2(kk),throne.dur2(kk));
n2 = n1 + length(tone2) - 1;
xb(n1:n2) = tone2; %<------- Insert the note
n1 = n2 + 1;
end
xb(length(xb)+1:length(xt)) = 0; %bass voice has a much shorter duration currently - padding to same size as xt with 0's at the end.
%If you add more voices, you have to pad them all to the length of the longest one.
%xt = zeros(1, sum(tdur)*fs + length(keyst));
%xb = zeros(1, sum(bdur)*fs + 1);
%xa = zeros(1, sum(adur)*fs+1);
%xd = zeros(1, sum(ddur)*fs+1);
%xx = xt + xb + xa + xd
xx = xt + xb;
soundsc(xx,fs)
Of course you could just download the theme song somewhere and use [y,Fs] = audioread(filename) to convert it. But that wouldn't even remotely be as cool as what you are doing.
mn = 1
for kn = 1:199
for sn = 1:19773
if abs((x1c{kn+1,1}(sn)) - (x1c{kn,1}(sn))) >= 20
extract{mn} = x1c{kn+1,1}(sn);
mn = mn+1;
end
end
end
extend = cell2mat(extract) + 40;
How can I change the values of "x1c" with the values of "extend"?
You are performing the operation on a cell. Considering you're comparing numbers, this would be done far more efficiently when done with matrices.
I therefor suggest you convert the cell (or a subset of it) to a matrix and then use vectorized operations, like this:
>> a={[13, 2, 3], [14, 25, 8], [100, 9, 10], [101, 8, 32], [140, 20, 3]};
>>
>> x = transpose(reshape(cell2mat(a), 3, []));
>> z = abs(x(2:end, :) - x(1:end-1,:)) > 20;
>> z2 = [zeros(1,3); z]
z2 =
0 0 0
0 1 0
1 0 0
0 0 1
1 0 1
>> x(logical(z2)) = x(logical(z2)) - 200
x =
13 2 3
14 -175 8
-100 9 10
101 8 -168
-60 20 -197
There are two alternatives if you really must use cells (I don't recommend it for speed reasons).
store the indices (k, sn) of the cell items where your condition holds true. And then you'd have to loop over the elements again (very inefficient).
You'd store the previous and next cell "row" in temporary variables and compare using those. When the condition holds, edit in-place and take the temporary variable with you in the next iteration of the loop. The code below shows how this is done:
a={[13, 2, 3], [14, 25, 8], [100, 9, 10], [101, 8, 32], [140, 20, 3]};
curr_row = a{1};
for rowind=1:4
next_row = a{rowind+1};
for colind=1:3
if abs(next_row(1, colind) - curr_row(1, colind)) > 20
a{rowind+1}(1, colind) = a{rowind+1}(1, colind) + 40;
end
end
curr_row = next_row;
end
Say there is an array of n elements, and out of n elements there be some numbers which are much bigger than the rest.
So, I might have:
16, 1, 1, 0, 5, 0, 32, 6, 54, 1, 2, 5, 3
In this case, I'd be interested in 32, 16 and 54.
Or, I might have:
32, 105, 26, 5, 1, 82, 906, 58, 22, 88, 967, 1024, 1055
In this case, I'd be interested in 1024, 906, 967 and 1055.
I'm trying to write a function to extract the numbers of interest. The problem is that I can't define a threshold to determine what's "much greater", and I can't just tell it to get the x biggest numbers because both of these will vary depending on what the function is called against.
I'm a little stuck. Does anyone have any ideas how to attack this?
Just taking all the numbers larger than the mean doesn't cut it all the time. For example if you only have one number which is much larger, but much more numbers wich are close to each other. The one large number won't shift the mean very much, which results in taking too many numbers:
data = [ones(1,10) 2*ones(1,10) 10];
data(data>mean(data))
ans =
2 2 2 2 2 2 2 2 2 2 10
If you look at the differences between numbers, this problem is solved:
>> data = [16, 1, 1, 0, 5, 0, 32, 6, 54, 1, 2, 5, 3];
sorted_data = sort(data);
dd = diff(sorted_data);
mean_dd = mean(dd);
ii = find(dd> 2*mean_dd,1,'first');
large_numbers = sorted_data(ii:end);
large_numbers =
6 16 32 54
the threshold value (2 in this case) lets you play with the meaning of "how much greater" a number has to be.
If it were me I'd use a little more statistical insight, that would give the most flexibility for the code in the future.
x = [1 2 3 2 2 1 4 6 15 83 2 4 22 81 0 8 7 7 7 3 1 2 3]
EpicNumbers = x( x>(mean(x) + std(x)) )
Then you can increase or decrease the number of standard deviations to broaden or tighten your threshold.
LessEpicNumbers = x( x>(mean(x) + 2*std(x)) )
MoreEpicNumbers = x( x>(mean(x) + 0.5*std(x)) )
A simple solution would be to use find and a treshold based on the mean value (or multiples thereof):
a = [16, 1, 1, 0, 5, 0, 32, 6, 54, 1, 2, 5, 3]
find(a>mean(a))