Decrypt a 4-digit number - c

I just made a simple program in C that takes a 4-digit code and encrypts every digit (previously decomposed, that goes from 0 to 9) using this easy algorithm:
new_num1 = (old_num1 + 7) % 10;
new_num2 = (old_num2 + 7) % 10;
new_num3 = (old_num3 + 7) % 10;
new_num4 = (old_num4 + 7) % 10;
Now I want to make a decrypt.c program to decrypt 4-code digit previously encrypted.
In which way I can revert the number?
This is my code for crypter.c (in this example I also revert the first digit with third and second with fourth)
#include <stdio.h>
int main()
{
int codice;
int num1, num2, num3, num4, temp1, temp2, new_num1_temp, new_num2_temp;
printf("\n(LOLCrytter v0.1)\n\nInsert 4-digit code to crypt: -1 to exit ");
scanf("%d", &codice);
if(codice == -1)
return 0;
while(codice < 1000 || codice > 9999) {
printf("\nInsert NUMERIC (!) 4-digit code bru..: ");
scanf("%d", &codice);
}
// Get every digit by logic math and not by strings functions
temp1 = codice;
num1 = temp1 / 1000;
temp2 = temp1 % 1000;
num2 = temp2 / 100;
temp1 = temp2 % 100;
num3 = temp1 / 10;
num4 = temp1 % 10;
// Crypting...
num1 = (num1 + 7) % 10;
num2 = (num2 + 7) % 10;
num3 = (num3 + 7) % 10;
num4 = (num4 + 7) % 10;
// Crypting...
new_num1_temp = num3;
num3 = num1;
num1 = new_num1_temp;
new_num2_temp = num4;
num4 = num2;
num2 = new_num2_temp;
printf("\nNew code: %d%d%d%d\n\n", num1, num2, num3, num4);
return 0;
}

if input restricted to [0..9] (as code shows at the moment of the answer) then it will work: encryption of 8 is (8 + 7) % 10 = 5. Decryption is 10 + 5 - 7 = 8.
your custom algorithm in general: encryption of x is (x + 7) % m == r; decryption is: m + r - 7 == x
But author in question wants to "decrypt a 4-digit number" and just in case I need to make a caution if author considers changing the code: Mod operation is not bijection - it is not reversible: (0 + 7) % 10 = 7; (10 + 7) % 10 = 7.
if algorithm's input is only from range 0..9 then , for instance: 10 % 7 = 3; 7*1 + 3 = 10. That is 7 * (10 / 7) + 3 = 10. Every number a can be represented as a = m * (a/m) + r; where m is modulus, r - remainder. "/" integral devision.
Function of form (k + n) mod m is good for hash functions, used for random numbers generation. If you want to use simple encryption for learning you can achieve better results with minimum efforts - use XOR. Generate key and XOR it with plain text. To decrypt XOR encrypted text with the same key. Read about One-time pad One-time pad - very simple in implementation encryption technique but that cannot be cracked.
UPDATED: As cryptographer I would recommend you (if you are interested in learning basics of cryptography) starting to learn and implement classical simple crypto algorithms like: Caesar cipher, simple substitution, Vigener cryptosystem (they are available in wikipedia).
Your crypto function (t + 7) % 10 is very similar to Caeser educational cipher with some changes:
The encryption can be represented using modular arithmetic by first transforming the letters into numbers, according to the scheme, A → 0, B → 1, ..., Z → 25. Encryption of a letter x by a shift n can be described mathematically as,
Decryption is performed similarly,
Goog luck!

Related

How to add product digits rather than products themselves in C?

I am trying to finish an assignment in C for the CS50 course in which I must implement Luhn's algorithm to validate a credit card number. Here is a quick example to elaborate:
credit card number: 4003600000000014.
Now for every other digit, starting with the number’s second-to-last digit:
1-0-0-0-0-6-0-4
Let’s multiply each of the digits by 2:
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2
That gives us:
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8
Now let’s add those products’ digits (i.e., not the products themselves) together:
2 + 0 + 0 + 0 + 0 + 1 + 2 + 0 + 8 = 13
Now let’s add that sum (13) to the sum of the digits that weren’t multiplied by 2 (starting from the end):
13 + 4 + 0 + 0 + 0 + 0 + 0 + 3 + 0 = 20
Yup, the last digit in that sum (20) is a 0, so the number is valid.
I figured out how to extract each number in the credit card individually (I know my way is boring and probably not practical), so the next step is to multiply every other number by two and add (the products' digits, not the digits themselves) and this is what I need help of how to do it?
MY code:
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
long credit_card_number;
do
{
credit_card_number = get_long("Enter your credit card number: ");
}
while (credit_card_number < 1 || credit_card_number > 9999999999999999);
//American Express uses 15-digit numbers. American Express numbers start with 34 or 37
//MasterCard uses 16-digit numbers. MasterCard numbers start with 51, 52, 53, 54, or 55.
//Visa uses 13- and 16-digit numbers. Visa numbers start with 4.
// checksum
long last_number;
long credit_card_without_last_number;
long second_to_last_number;
long credit_card_without_second_number;
long third_number;
long credit_card_without_third_number;
long fourth_number;
long credit_card_without_fourth_number;
long fifth_number;
long credit_card_without_fifth_number;
long sixth_number;
long credit_card_without_sixth_number;
long seventh_number;
long credit_card_without_seventh_number;
long eighth_number;
long credit_card_without_eighth_number;
long ninth_number;
long credit_card_without_ninth_number;
long tenth_number;
long credit_card_without_tenth_number;
long eleventh_number;
long credit_card_without_eleventh_number;
long twelfth_number;
long credit_card_without_twelfth_number;
long thirteenth_number;
long credit_card_without_thirteenth_number;
long fourteenth_number;
long credit_card_without_fourteenth_number;
long fifteenth_number;
long credit_card_without_fifteenth_number;
long sixteenth_number;
long multiply_digits;
//separating each number starting from the last (right)in its own variable.
last_number = credit_card_number % 10;
credit_card_without_last_number = credit_card_number / 10;
second_to_last_number = credit_card_without_last_number % 10;
credit_card_without_second_number = credit_card_without_last_number / 10;
third_number = credit_card_without_second_number % 10;
credit_card_without_third_number = credit_card_without_second_number / 10;
fourth_number = credit_card_without_third_number % 10;
credit_card_without_fourth_number = credit_card_without_third_number / 10;
fifth_number = credit_card_without_fourth_number % 10;
credit_card_without_fifth_number = credit_card_without_fourth_number / 10;
sixth_number = credit_card_without_fifth_number % 10;
credit_card_without_sixth_number = credit_card_without_fifth_number / 10;
seventh_number = credit_card_without_sixth_number % 10;
credit_card_without_seventh_number = credit_card_without_sixth_number / 10;
eighth_number = credit_card_without_seventh_number % 10;
credit_card_without_eighth_number = credit_card_without_seventh_number / 10;
ninth_number = credit_card_without_eighth_number % 10;
credit_card_without_ninth_number = credit_card_without_eighth_number / 10;
tenth_number = credit_card_without_ninth_number % 10;
credit_card_without_tenth_number = credit_card_without_ninth_number / 10;
eleventh_number = credit_card_without_tenth_number % 10;
credit_card_without_eleventh_number = credit_card_without_tenth_number / 10;
twelfth_number = credit_card_without_eleventh_number % 10;
credit_card_without_twelfth_number = credit_card_without_eleventh_number / 10;
thirteenth_number = credit_card_without_twelfth_number % 10;
credit_card_without_thirteenth_number = credit_card_without_twelfth_number / 10;
fourteenth_number = credit_card_without_thirteenth_number % 10;
credit_card_without_fourteenth_number = credit_card_without_thirteenth_number / 10;
fifteenth_number = credit_card_without_fourteenth_number % 10;
credit_card_without_fifteenth_number = credit_card_without_fourteenth_number / 10;
sixteenth_number = credit_card_without_fifteenth_number % 10;
//Here I need the help to multiply these numbers by two and then add each product's
//digits to the rest of the unused numbers.
multiply_digits = (second_to_last_number*2)+(fourth_number*2)+(sixth_number*2)+(eighth_number*2)+(tenth_number*2)+(twelfth_number*2)+(fourteenth_number*2)+(sixteenth_number*2);
}
Try doing this instead
int main(){
long cNo = 4003600000000014;
int arr[16];
for(int i=0; i<16; i++){
arr[15-i] = cNo % 10;
cNo /= 10;
}
int multipliedSum = 0;
for(int i=0; i<16; i++){
if(i%2==1)
multipliedSum += arr[i];
else{
if(arr[i]*2<10){
multipliedSum += (arr[i]*2);
}else{
int num = arr[i]*2;
while(num){
multipliedSum += num%10;
num/=10;
}
}
}
}
printf("valid = %s\n",multipliedSum%10==0?" True": " False");
}
You will get the following
valid = True
A general algorithm for adding digits (assuming an integer type):
Initialize your sum to 0: sum = 0
Extract the lowest digit from the number using the % modulus operator: digit = number % 10
Add the value of that digit to the sum: sum += digit (shorthand for sum = sum + digit)
Divide the number by 10: number /= 10 (shorthand for number = number / 10
If the number is non-zero after dividing by 10, go back to 2
End
The modulus operator % returns the integer remainder of an integer division - 123 / 10 == 12 rem 3. So the remainder of dividing the number by 10 is the least significant decimal digit of the number. Notice that integer division gives you an integer result - 123 / 10 == 12, not 12.3.
You'll want to put this in a separate function, so you can write something like
int sumdig( int v )
{
...
}
int main( void )
{
int value = 123;
int sum = sumdig( value ); // sumdig will return 1 + 2 + 3, or 6
...
}
When you find yourself creating a bunch of separate variables of the same type with the same name except for some tacked-on ordinal (var1, var2, var3 or first_thing, second_thing, third_thing), that's a real strong hint you want to use an array. You can use an array to store the individual digits of your card number:
int number[16];
and use the % 10 method as described above to extract the individual digits:
long tmp = credit_card_number; // use a temporary so we preserve the original card number
for ( int i = 0; i < 16; i++ )
{
number[i] = tmp % 10;
tmp /= 10;
}
This means that the least significant (rightmost) card number digit will be stored in number[0] and the most significant (leftmost) card number digit will be stored in number[15], so be aware of that. For the purposes of validating the number it doesn't matter, but if you want to display the contents of the array you'll have to take that into account.
Using an array makes it easier to extract subsets of digits:
for ( int i = 1; i < 16; i += 2 ) // hit every other element starting at element 1
{
number[i] *= 2; // multiply these digits by 2
}
That loop above executes the "1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2" portion of your algorithm.
You should be able to figure out the rest from there. Hope this helps.
Hint: to extract one digit from a number, mod it by 10.
So say that you want to figure out the sum of the digits of a number, say 123456, you will do the following:
(pseudocode)
number=123456;
sum=0;
loop if number is not 0{
sum+=number % 10;
number-=number % 10;
number=(int)(number/10);
}
Now try to implement it as a function, say digit(), and when you are trying to add some numbers digit-wise, say 123 and 456, just do digit(123)+digit(456) instead.

Decryption - Get back the number after splitting C programming

I've just did an encryption using a simple C code. The encryption works like this, "Your application should read a 4 digit integer entered by the user and replace each digit with the result of adding 7 to the digit and getting the remainder after diving the new value by 10:
Let say I've entered 1234, the value after encryption will be 8,9,0,1.
I'm doing the encryption with the following code below:
num1 = ((digits/1000) + 7) % 10;
num2 = ((digits/100) + 7) % 10;
num3 = ((digits/10) + 7) % 10;
num4 = ((digits/1) + 7) % 10;
Now I would like to do a decryption, getting back the value I've entered. I'm wondering if I'm able to do a reverse modulo? A backwards calculation for %?
Meaning if a = 3 + 4, a = 7.. So what is 7 = b + 4 which is b = 7-4. I'm
What I've attempted so far is this:
dNum1= (digits/1000) % 10;
dNum2= (digits/100) %10;
dNum3= (digits/10) %10;
dNum4= (digits % 10) ;
The question is now: How do I retrieve the original value from the decrypted value(8,9,0,1)? (Original Value: 1234)
Since you encoded each digit by adding 7, you need to decode by subtracting 7. Then if the value is negative, add 10 to get back the expected value.
num1 = (digits/1000) - 7;
num2 = (digits/100) - 7;
num3 = (digits/10) - 7;
num4 = (digits % 10) - 7;
if (num1 < 0) num1+=10;
if (num2 < 0) num2+=10;
if (num3 < 0) num3+=10;
if (num4 < 0) num4+=10;
EDIT:
Better yet, you can add 3 and then mod by 10, which does the same thing. Thanks to psmears for suggesting this.
num1 = ((digits/1000) + 3) % 10;
num2 = ((digits/100) + 3) % 10;
num3 = ((digits/10) + 3) % 10;
num4 = ((digits/1) + 3) % 10;
EDIT2:
If you're translating the decoded digits directly from the encoded digits without moving the values back to digits first, do this:
dNum1 = (num1 + 3) % 10;
dNum2 = (num2 + 3) % 10;
dNum3 = (num3 + 3) % 10;
dNum4 = (num4 + 3) % 10;
that's an interesting question #stack. One thing I see is that you are using individual statements to assign values to num1,num2,num3,num4
but every encryption follows a defined pattern and implicit is that
every decryption does
And if you are successful in finding such pattern(Which I prefer to say mystery!), then these kind of encryption are near solved!
So I decided to find the pattern and I was successful in finding it for your encryption. ones you find pattern, for loop is very useful to repeat the process and thus encode given number.(same for the decoding too)
Note: I Don't know whether you require such a solution, but this is more useful as there are less number of variables which is a characteristic of any good program. and this code is only for 4 digit numbers... feel free to ask me if you want to extend it to n digited numbers :)
so! Here is my code:
#include<stdio.h>
#include<math.h>
int main()
{
//encryrption
int num,num1,i,e=0,d=0;
printf("enter 4 digit number:\n");
scanf("%d",&num);
num1=num;
for(i=3;i>=0;i--)
{
num1=(num)/(pow(10,i));
num1=(num1+7)%10;
e=(10*e)+num1;
}
printf("encryption = %d\n",e);
//decryption:
for(i=3;i>=0;i--)
{
num1=e/pow(10,i);
num1=((num1-7)%10);
d=(10*d)+num1;
}
printf("decryption = %d",d);
return 0;
}

How do I multiply a long integer with different numbers in C program?

I am very new to C programming and I am writing a program which takes a number which is suppose to be 9 digits long. After this I multiply each digit with either 1 or 2. I am using arrays to ask user to enter their numbers. I would like to know if there is a way to multiply those 9 numbers with different numbers as one integer instead of using arrays? Here is my code with arrays:
#include <stdio.h>
int main(void) {
int sin_num[9];
int num1;
int num2, num11, num12;
int num3, num4, num5, num6, num7, num8, num9, num10;
for(num1=0; num1<9; num1++) {
printf("Enter your SIN number one by one:");
scanf("%d", &sin_num[num1]);
}
num2 = sin_num[0] * 1;
num3 = sin_num[1] * 2;
num4 = sin_num[2] * 1;
num5 = sin_num[3] * 2;
num6 = sin_num[4] * 1;
num7 = sin_num[5] * 2;
num8 = sin_num[6] * 1;
num9 = sin_num[7] * 2;
num10 = sin_num[8] * 1;
Right now I am doing this:
element 1 * 1
element 2 * 2
element 3 * 1
But how can I do, lets say if I enter 123456789 multiply with different numbers:
123456789
121212121
Well I couldn't much understand what you were asking. Anyways hope this is what you are looking for.....
#include<stdio.h>
int main()
{
long int nine_digit_num;
int step=100000000;
int digit,input_num,i;
printf("Enter 9 digit number:\n");
scanf("%ld",&nine_digit_num);
for(i=1;i<=9;i++)
{
printf("Enter a number to multiply with the %d digit:\n",i);
scanf("%d",&input_num);
digit=nine_digit_num/step; // this and the next step are used to
digit=digit%10; // obtain the individual digits.
printf("%d*%d=%d\n",digit,input_num,digit*input_num);
step=step/10;
}
return 0;
}
I'm sure there are Luhn algorithm solutions already written that you could reference, but I'm going to invent my own right now just to have a walkthrough.
Since your input is only 9 digits, it will fit in a plain 32 bit variable. I'll use unsigned on the assumption it's 32 bits or bigger, but for production code, you'd likely want to use inttypes.h uint32_t and associated scanf macros.
#include <stdio.h>
int main(void) {
unsigned sin_num, checksum, digit;
int i;
printf("Enter your SIN as a 9 digit number using only digits:\n");
if (scanf(" %9u", &sin_num) < 1) ... do error handling or just exit ...
for (i = 0; sin_num; ++i) {
digit = sin_num % 10;
sin_num /= 10;
if (i & 1) { // Double odd digits (might have this backwards; check me for your case
digit *= 2;
if (digit >= 10) digit = digit % 10 + digit / 10; // Luhn carry is strange
}
checksum += digit;
}
... do whatever else you need to do ...
It's not a single mathematical operation because Luhn's carry is too weird for magic number tricks, but it's still much more straightforward than a bunch of single digit scanf calls and array storage.

how to check if the / operator has no remainder in C?

I want to check if the / operator has no remainder or not:
int x = 0;
if (x = 16 / 4), if there is no remainder:
then x = x - 1;
if (x = 16 / 5), if remainder is not zero:
then x = x + 1;
How to check if there are remainder in C? and
How to implement it?
Frist, you need % remainder operator:
if (x = 16 % 4){
printf("remainder in X");
}
Note: it will not work with float/double, in that case you need to use fmod (double numer, double denom);.
Second, to implement it as you wish:
if (x = 16 / 4), if there is no remainder, x = x - 1;
If (x = 16 / 5), then x = x + 1;
Useing , comma operator, you can do it in single step as follows (read comments):
int main(){
int x = 0, // Quotient.
n = 16, // Numerator
d = 4; // Denominator
// Remainder is not saved
if(x = n / d, n % d) // == x = n / d; if(n % d)
printf("Remainder not zero, x + 1 = %d", (x + 1));
else
printf("Remainder is zero, x - 1 = %d", (x - 1));
return 1;
}
Check working codes #codepade: first, second, third.
Notice in if-condition I am using Comma Operator: ,, to understand , operator read: comma operator with an example.
If you want to find the remainder of an integer division then you can use the modulus(%):
if( 16 % 4 == 0 )
{
x = x - 1 ;
}
else
{
x = x +1 ;
}
use the % operator to find the remainder of a division
if (number % divisor == 0)
{
//code for perfect divisor
}
else
{
//the number doesn't divide perfectly by divisor
}
use modulous operator for this purpose.
if(x%y == 0) then there is no remainder.
In division operation, if the result is floating point, then only integer part will be returned and decimal part will be discarded.
you can use Modulous operator which deals with remainder.
The modulus operator (represented by the % symbol in C) computes the remainder. So:
x = 16 % 4;
x will be 0.
X = 16 % 5;
x will be 1

Decimal to octal in C

I have just begun teaching myself C out of K.N King's C Programming: A Modern Approach (2ndEdn).
I'm enjoying it, but am hoping to post the odd question here for advice if appropriate because unfortunately I don't have a tutor and some bits raise more questions then they answer!
I'm doing a question on taking an integer entered and displaying it in octal. It says there is an easy way to do it, but that comes later in the book. I have come up with the following:
// Convert a number to octal
int n, n2, n3, n4, n5, n6;
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
n6 = n % 8;
n5 = (n / 8) % 8;
n4 = ((n / 8) / 8) % 8;
n3 = (((n / 8) / 8) / 8) % 8;
n2 = ((((n / 8) / 8) / 8) / 8) % 8;
printf("%d%d%d%d%d", n2, n3, n4, n5, n6);
It works OK, but I'm not good at math and was wondering if there is a more efficient way of doing this or have I done it the only way possible...
If anyone else has the book it's Q4 p.71.
Thanks for your time.
Andrew
P.S I did look in the search engine but couldn't find anything that was doing it this 'slower' way!
Everyone is right in saying that there's a built-in way to do that with printf. But what about doing it yourself?
The first thing that came to mind is that one octal digit is exactly three bits. Therefore you can do the conversion this way:
Loop while n != 0
Isolate the leftmost 3 bits of n into d and print d
Shift n 3 bits to the left
The code is trivial, but I 'm not providing it so you can do it yourself (you will need to be familiar with the bitwise and shift operators in order to do it).
The easy way is probably to use printf()'s %o format specifier:
scanf("%d", &n);
printf("%o", n);
Others have posted the real, production code answer, and now I see from your comments that you haven't done loops yet. Perhaps your book is trying to teach you about recursion:
void print_oct(int n)
{
if (n != 0) {
print_oct(n / 8);
printf("%d", n % 8);
}
}
This works for n > 0.
With loops you can roll up your five very similar lines like this:
for (int d = 8 * 8 * 8 * 8; d > 0; d /= 8)
printf("%d", n / d % 8);
printf("\n");
d will start at 8 * 8 * 8 * 8, which is the divisor you use for n2 and then step through 8 * 8 * 8, 8 * 8, 8 and finally 1, which is the divisor for n6, printing each digit along the way.
A good compiler will actually optimize this by unrolling it back into five lines, so you'll get almost the same thing you started with. The advantage of writing it as a loop is that you can't make a mistake in just one of the lines.
The compiler will also take care of replacing divisions by 8 with shifts by 3 bits. Both give the same result in binary, but the latter is faster.
/* Converts a positive base_10 into base_b */
int DecimalToBase(int n, int b)
{
int rslt=0, digitPos=1;
while (n)
{
rslt += (n%b)*digitPos;
n /= b;
digitPos *= 10;
}
return rslt;
}
Use %o format specifier inside printf
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
printf("%o", n);
Since only basics are introduced you don't want (at least at this point) to use functions, loops, bitwise operators, %o format specifier and all that stuff. Here is my basic solution:
int n, d1, d2, d3, d4, d5, o;
printf("Enter a number between 0 and 32767: ");
scanf("%d", &n);
d5 = n % 8;
n /= 8;
d4 = n % 8;
n /= 8;
d3 = n % 8;
n /= 8;
d2 = n % 8;
n /= 8;
d1 = n % 8;
o = 10000 * d1 + 1000 * d2 + 100 * d3 + 10 * d4 + d5;
printf("In octal, your number is: %.5d\n", o);
Note that since n is not needed in output, you can modify (divide) it for every step (thus saving divides, which are computationally and relatively expensive). You are safe up to 32767 (in octal: 77777), as 32768 (8*8*8*8*8 = 8^5 = (2^3)^5 = 2^15) is the first number, that requires six digits in octal: 100000.
This o variable is not really needed, morever it will not work when int is signed 16-bit (on some ancient system), so from this point it's better to just print separate digits.
Existing answers aren't clean enough for my liking. Here's mine:
#include <stdio.h>
#define OCTALBASE 8
#define OCTALSIZE 8
int main(int argc, char **argv) {
int indecimal = 1337;
char output[OCTALSIZE + 1];
output[OCTALSIZE] = '\0';
int outindex = OCTALSIZE;
int outdigit = 0;
int outvalue = indecimal;
while (--outindex >= 0) {
outdigit = outvalue % OCTALBASE;
if (outvalue > 0 || outdigit > 0)
{ output[outindex] = '0' + outdigit; }
else { output[outindex] = ' '; }
outvalue /= OCTALBASE;
}
fprintf(stdout, "{ DEC: %8d, OCT: %s }\n", indecimal, output);
fflush(stdout);
return 0;
}
Result:
{ DEC: 1337, OCT: 2471 }
Convert Decimal to Octal in C Language
#include<stdio.h>
#include<conio.h>
void main()
{
A:
long int n,n1,m=1,rem,ans=0;
clrscr();
printf("\nEnter Your Decimal No :: ");
scanf("%ld",&n);
n1=n;
while(n>0)
{
rem=n%8;
ans=(rem*m)+ans;
n=n/8;
m=m*10;
}
printf("\nYour Decimal No is :: %ld",n1);
printf("\nConvert into Octal No is :: %ld",ans);
printf("\n\nPress 0 to Continue...");
if(getch()=='0')
goto A;
printf("\n\n\n\tThank You");
getch();
}

Resources