I'm supposed to crack the Caesar cipher.
I have to declare a function crack : int * int -> int so that if (k, c) are of the type int, where k is the decrypted text and c the encrypted text, calling crack(k, c) will return the key (mod 10) n, which is needed to get c to k.
An example would be that calling crack(20458790, 64892134) would return 4.
If c isn't a correctly encoding of k, the function doesn't have to actually work.
I hope I'm being clear enough here. I understand the actual assignment here (I have k and c, I need n), but I don't know how to show it in my code.
You didn't specify what should happen when the second number isn't a caesar encoding of the first, so I'm going to assume it does not matter.
So in order to get, you just need to take any digit (most conveniently the last) from the first number and subtract that from the digit at the same position of the second number.
In other words, you can just do: (c mod 10 - k mod 10) mod 10
Related
void solve(string op, int n, int zeros, int ones)
{
if(n==0){
cout<<op<<" ";
return;
}
string op1 = op;
op1.push_back('1');
solve(op1, n-1, zeros, ones+1);
if(ones > zeros){
string op2 = op;
op2.push_back('0');
solve(op2, n-1, zeros+1, ones);
return;
}
}
what is the time complexity for the solve function? is it O(2^N)? can someone please explain how you approach to find complexities for recursive functions?
link to question: https://www.geeksforgeeks.org/print-n-bit-binary-numbers-1s-0s-prefixes/
So, we want to estimate the worse case here. The worse case would be if the condition (ones > zeros) always returns to true. Is it possible? Yes, if ones-zeros >= n. Since I don't know the context of your task, I may assume it.
Let T(n) is the complexity of your function. Your function calls itself with (n-1) two times. That means,
T(n) = T(n-1) + T(n-1) + c
where c is a constant for routines you are doing else like appending '1' or '0', condition evaluating etc. what is not depended on n.
So,
T(n) = 2T(n-1) + c =
= 2(2T(n-2) + c) + c = 4T(n-2) + 3c =
= 4(2T(n-3) + c) + 3c = 8T(n-3) + 7c =
= ...
= 2^k*T(n-k) + (2^k-1)*c
so if (n-k) == 0, you are done, as T(0) = z. So, we are done when k == n. Regarding z it is not obvious. In the current implementation we do output a string which is O(n). If we would just count strings it would be O(1). If we printing is essential the final complexity would be O(n2^n) if not then O(2^n)
That means,
T(n) = z*2^n + (2^n - 1)*c = O(z2^n)
[UPDATE1]
after realizing the real problem which was not clear from the code snippet but became clear after reading the info from the provided link, I would say that the complexity is different.
The calculation above is still true under assumptions was made.
Now, to this problem. We want to find all sequences of 1 and 0 of length n where each prefix contains 1's not less than the number of 0's in this prefix.
The algorithm provides the solution to this problem. As you can notice at each recursive call, the algo adds either 0 or 1 to the resulting sequence. That means the number of recursive calls is exactly the umber of symbols in the resulting strings.
We know that the length of each resulting string is n. So, we need to figure out the number of strings. Let's take a look what your program finds for different n's:
n | number of strings
-----------------------
1 | 1
2 | 2
3 | 3
4 | 6
5 | 10
6 | 20
7 | 35
8 | 70
So, if you look carefully, you will recognize that these are binomial coefficients C(n, n/2). This binomial coefficient can be estimated as ~2^n/(\pi * n/2) by large n. So, the complexity of the algo is O(2^n/(n)). However, if we also consider printing at end of recursion, we need to multiply with n, as it is the length of the outputted string. So, we end up with O(2^n)
To be clean, we need to prove that our assumption is correct. Hopefully you can do it by induction or other methods.
[UPDATE2]
Your implementation suffers from coping the string at each iteration. This slows down the execution by factor n. You can avoid it by passing a reference to the string and removing the added character after a recursive call like this:
void solve(string &op, int n, int zeros, int ones)
{
if(n==0){
cout<<op<<" ";
return;
}
op.push_back('1');
solve(op, n-1, zeros, ones+1);
op.pop_back();
if(ones > zeros){
op.push_back('0');
solve(op, n-1, zeros+1, ones);
op.pop_back();
return;
}
}
If I understand you correctly, the time complexity for the function is O(N*2^N). I use the recursion tree to analyze the results.
I have 4 digit number from 0000 to 1440. I want to generate an equivalent four digit number. That means I can reverse the number from the equivalent number. Basic requirement is the equivalent number must be completely different from the original one. Is there a good equation to do this?
For example, each digit can be replaced by 10 - digit. Thus, 1440 becomes 9660, and 1254 becomes 9756.
Thanks.
You can use a Linear Congruential Generator with a period of 10000. This is a pseudo-random number generator that cycles through each number in the range of 0-9999 once and only once. To generate your number, just take the original number and calculate the next number in the LCG sequence.
An LCG generates random numbers using the following formula:
Xn+1 = ((Xn * a) + c) mod m
To generate 4-digit numbers m should be 10000 (range of 0-9999).
To guarantee no repeats (a "full period") you have to select values for a and c using the following criteria:
c and m are relatively prime
a - 1 is divisible by all prime factors of m
a - 1 is a multiple of 4 if m is a multiple of 4.
The prime factors of 10000 are 2 and 5, and it's also divisible by 4, so any multiple of 20 + 1 will work as a suitable value of a. For c just choose a reasonably large prime number.
e.g: m = 10000, a = 4781, c = 7621
To go the other way, you need to make the function reversible. See this answer for an explanation of the math behind that.
Here's a simple implementation:
#define M (10000)
#define A (4781)
#define C (7621)
int extendedEuclidY(int a, int b);
int extendedEuclidX(int a, int b)
{
return (b==0) ? 1 : extendedEuclidY(b, a-b*(a/b));
}
int extendedEuclidY(int a, int b)
{
return (b==0) ? 0 : extendedEuclidX(b, a-b*(a/b)) - (a/b) * extendedEuclidY(b, a-b*(a/b));
}
int forward(int x)
{
return ((x*A)+C)%M;
}
int backward(int x)
{
return ((extendedEuclidX(A, M)*(x-C)%M)+M)%M;
}
int main()
{
int x;
for(x=0; x<1440; x++)
{
printf("%d <-> %d\n", backward(forward(x)), forward(x));
}
return 0;
}
I've adapted the extendedEuclid functions from the linked answer.
forward(x) finds your equivalent number, backward(x) gets the original back.
This is, perhaps, more of a comment.
I think your question is rather vague, because you don't define "completely different". Typical "easy" ways are something like:
Reverse the number.
Substitute the digits for other digits (an easy way is to increment each digit by 1).
Substitute pairs of digits for other pairs.
And, you can of course combine these.
In your case, you are starting with a range of 1,441 and mapping to a much larger range (10,000). This actually gives you are larger range of possible mappings.
However, the key point is "how different is different"? You should modify your question to explain that point.
I've generated p,q,n, and totient, and need to generate e where 1 < e < totient and e and totient are coprime. The problem I'm running into with my code is that I'm first generating totient (normal (p-1)*(q-1) way) but when i try to generate a coprime e, it usually runs forever with this code
const mpz_class RsaKeys::compute_e(mpz_class totient) const {
dgrandint e(bits_);
while ((e.get_mpz_class() < totient) ||
!is_coprime(e.get_mpz_class(), totient)) {
std::cerr<<e.get_mpz_class()<< " is not coprime with "<<totient<<std::endl;
e.reroll();
}
return e.get_mpz_class();
I'm testing with low bit integers 8-32, and will actually need to handle 1024 bit values, but I need a way to first check if the totient generated has any arbitrary number of possible values that would make it coprime. I have only found ways of checking whether values are coprime, but not if there exists a complementary coprime value for a number that already exists.
The value of e doesn't need to be random, indeed most RSA systems use one of a small number of common e values, with the most widely used being 65537.
I'm currently writing my own ASE/RSA encryption program in C++ for Unix. I've been going through the literature for about a week now, and I've started to wrap my head around it all but I'm still left with some pressing questions:
1) Based on my understanding, an RSA key in its most basic form is the combination of the product of the two primes (R) used and the exponents. It's obvious to me that storing the key in such a form in plaintext would defeat the purpose of encryption anything at all. Therefore, in what form can I store my generated public and private keys? Ask the user for a password and do some "simple" shift/replacing on the individual digits of the key with an ASCII table? Or is there some other standard I haven't run across? Also, when the keys are generated, are R and the respective exponent simply stored sequentially? i.e. ##primeproduct####exponent##? In that case, how would a decryption algorithm parse the key into the two separate values?
2) How would I go about programatically generating the private exponent, given that I've decided to use 65537 as my public exponent for all encryptions? I've got the equation P*Q = 1mod(M), where P and Q and the exponents and M is the result of Euler's Totient Function. Is this simply a matter of generating random numbers and testing their relative primality to the public exponent until you hit pay dirt? I know you can't simply start from 1 and increment until you find such a number, as anyone could simply do the same thing and get your private exponent themselves.
3) When generating the character equivalence set, I understand that the numbers used in the set can't be must be less than and relatively prime to P*Q. Again, this is a matter of testing relative primality of numbers to P*Q. Is the speed of testing relative primality independent of the size of the numbers you're working with? Or are special algorithms necessary?
Thanks in advance to anyone who takes the time to read and answer, cheers!
There are some standard formats for storing/exchanging RSA keys such as RFC 3447. For better or worse, most (many, anyway) use ASN.1 encoding, which adds more complexity than most people like, all by itself. A few use Base64 encoding, which is a lot easier to implement.
As far as what constitutes a key goes: in its most basic form, you're correct; the public key includes the modulus (usually called n) and an exponent (usually called e).
To compute a key pair, you start from two large prime numbers, usually called p and q. You compute the modulus n as p * q. You also compute a number (often called r) that's (p-1) * (q-1).
e is then a more or less randomly chosen number that's prime relative to r. Warning: you don't want e to be really small though -- log(e) >= log(n)/4 as a bare minimum.
You then compute d (the private decryption key) as a number satisfying the relation:
d * e = 1 (mod r)
You typically compute this using Euclid's algorithm, though there are other options (see below). Again, you don't want d to be really small either, so if it works out to a really small number, you probably want to try another value for e, and compute a new d to match.
There is another way to compute your e and d. You can start by finding some number K that's congruent to 1 mod r, then factor it. Put the prime factors together to get two factors of roughly equal size, and use them as e and d.
As far as an attacker computing your d goes: you need r to compute this, and knowing r depends on knowing p and q. That's exactly why/where/how factoring comes into breaking RSA. If you factor n, then you know p and q. From them, you can find r, and from r you can compute the d that matches a known e.
So, let's work through the math to create a key pair. We're going to use primes that are much too small to be effective, but should be sufficient to demonstrate the ideas involved.
So let's start by picking a p and q (of course, both need to be primes):
p = 9999991
q = 11999989
From those we compute n and r:
n = 119999782000099
r = 119999760000120
Next we need to either pick e or else compute K, then factor it to get e and d. For the moment, we'll go with your suggestion of e=65537 (since 65537 is prime, the only possibility for it and r not being relative primes would be if r was an exact multiple of 65537, which we can verify is not the case quite easily).
From that, we need to compute our d. We can do that fairly easily (though not necessarily very quickly) using the "Extended" version of Euclid's algorithm, (as you mentioned) Euler's Totient, Gauss' method, or any of a number of others.
For the moment, I'll compute it using Gauss' method:
template <class num>
num gcd(num a, num b) {
num r;
while (b > 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
template <class num>
num find_inverse(num a, num p) {
num g, z;
if (gcd(a, p) > 1) return 0;
z = 1;
while (a > 1) {
z += p;
if ((g=gcd(a, z))> 1) {
a /= g;
z /= g;
}
}
return z;
}
The result we get is:
d = 38110914516113
Then we can plug these into an implementation of RSA, and use them to encrypt and decrypt a message.
So, let's encrypt "Very Secret Message!". Using the e and n given above, that encrypts to:
74603288122996
49544151279887
83011912841578
96347106356362
20256165166509
66272049143842
49544151279887
22863535059597
83011912841578
49544151279887
96446347654908
20256165166509
87232607087245
49544151279887
68304272579690
68304272579690
87665372487589
26633960965444
49544151279887
15733234551614
And, using the d given above, that decrypts back to the original. Code to do the encryption/decryption (using hard-coded keys and modulus) looks like this:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <functional>
typedef unsigned long long num;
const num e_key = 65537;
const num d_key = 38110914516113;
const num n = 119999782000099;
template <class T>
T mul_mod(T a, T b, T m) {
if (m == 0) return a * b;
T r = T();
while (a > 0) {
if (a & 1)
if ((r += b) > m) r %= m;
a >>= 1;
if ((b <<= 1) > m) b %= m;
}
return r;
}
template <class T>
T pow_mod(T a, T n, T m) {
T r = 1;
while (n > 0) {
if (n & 1)
r = mul_mod(r, a, m);
a = mul_mod(a, a, m);
n >>= 1;
}
return r;
}
int main() {
std::string msg = "Very Secret Message!";
std::vector<num> encrypted;
std::cout << "Original message: " << msg << '\n';
std::transform(msg.begin(), msg.end(),
std::back_inserter(encrypted),
[&](num val) { return pow_mod(val, e_key, n); });
std::cout << "Encrypted message:\n";
std::copy(encrypted.begin(), encrypted.end(), std::ostream_iterator<num>(std::cout, "\n"));
std::cout << "\n";
std::cout << "Decrypted message: ";
std::transform(encrypted.begin(), encrypted.end(),
std::ostream_iterator<char>(std::cout, ""),
[](num val) { return pow_mod(val, d_key, n); });
std::cout << "\n";
}
To have even a hope of security, you need to use a much larger modulus though--hundreds of bits at the very least (and perhaps a thousand or more for the paranoid). You could do that with a normal arbitrary precision integer library, or routines written specifically for the task at hand. RSA is inherently fairly slow, so at one time most implementations used code with lots of hairy optimization to do the job. Nowadays, hardware is fast enough that you can probably get away with a fairly average large-integer library fairly easily (especially since in real use, you only want to use RSA to encrypt/decrypt a key for a symmetrical algorithm, not to encrypt the raw data).
Even with a modulus of suitable size (and the code modified to support the large numbers needed), this is still what's sometimes referred to as "textbook RSA", and it's not really suitable for much in the way of real encryption. For example, right now, it's encrypting one byte of the input at a time. This leaves noticeable patterns in the encrypted data. It's trivial to look at the encrypted data above and see than the second and seventh words are identical--because both are the encrypted form of e (which also occurs a couple of other places in the message).
As it stands right now, this can be attacked as a simple substitution code. e is the most common letter in English, so we can (correctly) guess that the most common word in the encrypted data represents e (and relative frequencies of letters in various languages are well known). Worse, we can also look at things like pairs and triplets of letters to improve the attack. For example, if we see the same word twice in succession in the encrypted data, we know we're seeing a double letter, which can only be a few letters in normal English text. Bottom line: even though RSA itself can be quite strong, the way of using it shown above definitely is not.
To prevent that problem, with a (say) 512-bit key, we'd also process the input in 512-bit chunks. That means we only have a repetition if there are two places in the original input that go for 512 bits at a time that are all entirely identical. Even if that happens, it's relatively difficult to guess that that would be, so although it's undesirable, it's not nearly as vulnerable as with the byte-by-byte version shown above. In addition, you always want to pad the input to a multiple of the size being encrypted.
Reference
https://crypto.stackexchange.com/questions/1448/definition-of-textbook-rsa
I want to learn a bit of OCaml, just to get a taste of a programming language other than C++ and Java. I will be very greatful if you help me with the following program: basically the user inputs a positive integer. The sum of all integers from N to 0 is printed.
Obviously you create an integer N, let the user enter its value. Create a variable sum of type int. Have a for loop which will add N to sum and then decrement N's value by one. The loop will run while N is greater than 1. I have no idea how to do this in OCaml's syntax though.
Any help would be highly appreciated.
The way you describe your algorithm is how you would typically implement it in C++ or in Java. You can write it the same way in OCaml, but the idiomatic way would be a recursive function that does not mutate variables, as follows:
let rec print_sum acc n =
if n <= 0
then Printf.printf "Sum: %d\n" acc
else print_sum (acc + n) (n - 1)
Invoke with: print_sum 0 11 ;;
To write a recursive function:
First think of the base case when it is not necessary to recurse. This will save you from forgetting it (here, it's the case n <= 0)
The general case: how can you get one step closer to the base case already written? Here it's by invoking the function with n-1.