private double always returning 0 - c#

I have this function:
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach(int c in asciiBytes)
{
total = total + c;
total = total * (5 * (c ^ 2) / (c*6));
}
return Math.Round(total);
}
This is used to get a total of a strings ASCII values but does some math along the way rather than just adding. I need this to return the total, but is currently returning 0. How can I make it return the correct value? (PS: It needs to return an integer, but this can be in the datatype of a double for conversion later. Basically just need it to return a whole number.) (PSPS: I don't know what the string will be, it's up to the end user)
_

You probably misunderstood the ^ sign. It stands for a bitwise exclusive or, rather than an exponentiation. If you want to use the latter, use this:
total = total * (5 * (Math.Pow (c, 2) / (c * 6));
However, you could write it shorter/more beautiful/more efficient as well:
total *= (5 * (c * c) / (6 * c));
I replaced the Pow, as it is slower than a simple multiplication and used an assignment-operator.
Furthermore, the equation itself can be simplified:
total *= c * (5 / 6);
However, you should still mark the numbers as doubles, as 5/6 would result in 0 otherwise:
total *= c * (5.0 / 6.0)
For more information on exponentiation in C#, have a look at this.
By the way, the ^ sign takes every bit of the numbers and compares them. The new value will be 1 if the first bit or the second bit, but not both bits are 1.
So for example 0101 xor 1110 would result in 1011.

You have casting problem. The c variable is integer. Your problem is in the total = total * (5 * (c ^ 2) / (c*6)); expression.
Because the internal results (c ^ 2) and (c*6) aren't double, when the division result has floating point such as 0.nnnnn, the final result isn't double and you get only the 0 which is the real part of the number. And the result expression (5 * (c ^ 2) / (c*6)) as an Integer is 0. Finally the expression is as total=total * (0);
Use internal castings in your code
Replace your code with the following :
total = total * (5 * ((double)(c ^ 2)) / ((double)(c * 6)));
Please run the following code
static private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
double dC = c;
total = total + c;
double cXor2 = c ^ 2;
double c6 = c * 6;
double fiveCXor2 = 5 * cXor2;
double semiFinal = fiveCXor2 / c6;
double final = total * semiFinal;
Console.WriteLine("c = " + (c).ToString());
Console.WriteLine("c ^ 2 = " + (cXor2).ToString());
Console.WriteLine("c * 6 = " + (c6).ToString());
Console.WriteLine("5 * (c ^ 2) = " + (fiveCXor2).ToString());
Console.WriteLine("semi final = " + semiFinal);
Console.WriteLine("final = " + final);
Console.WriteLine("--------------------------------------------");
total = total * (5 * (c ^ 2) / (c * 6));
Console.WriteLine("TOTAL = " + total);
Console.WriteLine("--------------------------------------------");
}
return Math.Round(total);
}
Sample result is :
c = 97
c ^ 2 = 99
c * 6 = 582
5 * (c ^ 2) = 495
semi final = 0.850515463917526
final = 82.5
--------------------------------------------
TOTAL = 0
--------------------------------------------
c = 98
c ^ 2 = 96
c * 6 = 588
5 * (c ^ 2) = 480
semi final = 0.816326530612245
final = 80
--------------------------------------------
TOTAL = 0
--------------------------------------------
As you can see the problem is casting
Because the c variable is int the casting procedure is :
step 1
[double] = [double] * ([int] * ([int] ^ [int] ) / ([int] * [int] ))
total = total * (5 * (c ^ 2 ) / (c * 6 ));
step 2
[double] = [double] * ([int] * ([int]) / ([int] ))
total = total * (5 * (X) / (Y) );
step 3
[double] = [double] * ([int] * [int]))
total = total * (5 * XdivY );
**CASTING PROBLEM : In this step the XdivY is integer and when the result is 0.1234 the INT result is 0**
step 4
[double] = [double] * ([double]))
total = total * (5mulXdivY );
here c# casting the 5mulXdivY 0 to double but the result is zero
step 5
[double] = [double]
total = 0

Problem is with the this line in your code
total = total * (5 * (c ^ 2) / (c*6));
c ^ 2 returns a smaller value than c*6. Now the operator / is integer division so the result of a smallnumber/largenumber will always return zero. This will make the value of variable total zero in every iteration of the loop. Change the code like this and it will give you the result you expect.
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
total = total + c;
total = total * (5 * (double)(c ^ 2) / (double)(c * 6));
}
return Math.Round(total);
}
Hope it helps.

Add double to one of the ints
private double getTotal(string str)
{
double total = 0;
byte[] asciiBytes = Encoding.ASCII.GetBytes(str);
foreach (int c in asciiBytes)
{
total = total + c;
total = total * ((double)5 * (c ^ 2) / (c * 6));
}
return Math.Round(total);
}

Related

What's wrong in this formula when calculating it with C#?

I need to calculate a value based on a formula that I've checked there, as we can see in this screenshot:
I've tried to this equation in my C# app, but I don't get the expected values.
For example, I've created a basic console app:
public static void Calculate()
{
var values = new double[] { 1, 0.75, 0.5, 0.25, 0};
// y = - ((4/3) * x^3) + (3 * x^2) - ((2/3) * x)
foreach (var value in values)
{
var calcul1 = - ((4 / 3) * Math.Pow(value, 3))
+ (3 * Math.Pow(value, 2))
- ((2 / 3) * value);
var calcul2 = ((-4 / 3) * (value * value * value))
+ (3 * (value * value))
+ ((-2 / 3) * value);
Console.WriteLine($"value: {value} - calcul1: {calcul1} / calcul2: {calcul2}");
}
}
I get these results, that are not close to the expected results:
value: 1 - calcul1: 2 / calcul2: 2
value: 0.75 - calcul1: 1.265625 / calcul2: 1.265625
value: 0.5 - calcul1: 0.625 / calcul2: 0.625
value: 0.25 - calcul1: 0.171875 / calcul2: 0.171875
value: 0 - calcul1: 0 / calcul2: 0
What's wrong? Is it related to the use of double?
I refactored your code in order to obtain the correct values.
If you perform a division calculation without a explicit casting c# Implicitly cast to an integer, discarding the decimal part:
public static void Calculate()
{
var values = new double[] { 1, 0.75, 0.5, 0.25, 0};
// y = - ((4/3) * x^3) + (3 * x^2) - ((2/3) * x)
foreach (var value in values)
{
double firstFraction = (double)4/3;
double secondFraction = (double)2/3;
var calcul1 = - (firstFraction * Math.Pow(value, 3))
+ (3 * Math.Pow(value, 2))
- (secondFraction * value);
var calcul2 = ((firstFraction*-1) * (value * value * value))
+ (3 * (value * value))
+ ((secondFraction*-1) * value);
Console.WriteLine($"value: {value} - calcul1: {calcul1} / calcul2: {calcul2}");
}
}
You need to be more carefull with your data types.
as a test try to show the output for
var calc = (4 / 3) * 0.5;
Console.WriteLine(calc); //-> shows 0.5
because 4 and 3 are integers which is a data type without decimal point, 4/3 = 1
you can force 4 and 3 to be evaluated as doubles using literals floating point documentation
like this:
var calc = (4D / 3D) * 0.5;
Console.WriteLine(calc); //-> shows 0.666666666666667
see dotnetfiddle for an online example

BBP algorithm get nth digit of PI?

I am trying to turn the BBP Formula (Bailey-Borwein-Plouffe) in to C# code, it is digit extraction of pi in base 16 (spigot algorithm), the idea is give the input of what index/decimal place you want of pi then get that single digit. Let's say I want the digit that are at the decimal place/index 40000 (in base 16) without having to calculate pi with 40000 decimals because I don't care about the other digits.
Anyhow here is the math formula, (doesn't look like it should be to much code? )
Can't say I understand 100% what the formal mean, if I did I probably be able to make it in to code, but from my understanding looking at it.
Is this correct?
pseudo code
Pi = SUM = (for int n = 0; n < infinity;n++) { SUM += ((4/((8*n)+1))
- (2/((8*n)+4)) - (1/((8*n)+5)) - (1/((8*n)+6))*((1/16)^n)) }
Capital sigma basically is like a "for loop" to sum sequences together?
example
and in C# code:
static int CapSigma(int _start, int _end)
{
int sum = 0;
for(int n = _start; n <= _end; n++)
{
sum += n;
}
return (sum);
}
Code so far (not working):
static int BBPpi(int _precision)
{
int pi = 0;
for(int n = 0; n < _precision; n++)
{
pi += ((16 ^ -n) * (4 / (8 * n + 1) - 2 / (8 * n + 4) - 1 / (8 * n + 5) - 1 / (8 * n + 6)));
}
return (pi);
}
I'm not sure how to make it in to actual code also if my pseudo code math is correct?
How to sum 0 to infinity? Can't do it in a for loop and also where in the formula is the part ("input") that specify what nth (index) digit you want to get out? is it the start n (n = 0)? so too get digit 40000 would be n =40000?
You need to cast to double :
class Program
{
static void Main(string[] args)
{
double sum = 0;
for (int i = 1; i < 100; i++)
{
sum += BBPpi(i);
Console.WriteLine(sum.ToString());
}
Console.ReadLine();
}
static double BBPpi(int n)
{
double pi = ((16 ^ -n) * (4.0 / (8.0 * (double)n + 1.0) - 2 / (8.0 * (double)n + 4.0) - 1 / (8.0 * (double)n + 5.0) - 1.0 / (8.0 * (double)n + 6.0)));
return (pi);
}
}

How do I calculate an array of very large numbers without getting NaN in my output?

I made a calculator that works for small numbers but when the results get too large it returns NaN
List<string> memory = new List<string> { };
string display = "";
while (display.Contains("%") == false)
{
string line = ReadLine();
display = line;
memory.Add(line);
}
float result = float.Parse(memory[0]);
for (int i = 1; i < memory.Count; i++)
{
string temp = memory[i];
char[] _temp = temp.ToCharArray();
_temp = _temp.Where(x => x > _temp[0]).ToArray();
float num = float.Parse(string.Join("", _temp));
if (temp.Contains("+") == true) result += num;
else if (temp.Contains("-") == true) result -= num;
else if (temp.Contains("*") == true) result *= num;
else if (temp.Contains("/") == true) result /= num;
else if (temp.Contains("%") == true) result %= num;
}
Take these numbers for example:
797 * 2 + 38 * 212 * 275 * 806 * 67 * 9939 + 7 + 74 + 515 + 610 * 516 * 6921
+ 4 * 2 * 494 * 3153 * 8 + 2501 * 769 + 4 * 2472 + 1 * 21 * 6535 + 30 + 26
+ 44 + 240 + 88 * 1111 * 817 * 1576 + 551 * 535 + 9150 + 36 * 85 * 4598
* 9276 * 766 + 584 + 5 * 1 + 7 + 45 * 8152 % 7984
I enter each number in a new readline with the math symbol infront of it.
If you test it with these numbers just be aware.
I've looked everywhere and cant figure out a solution to this problem so that it can return a real number.
Anyone know what I can do to fix this?
The values you are using are too large for float. When the value gets too large for your float, it returns PositiveInfinity (or NegativeInfinity) instead of a number value. According to MSDN:
This constant is returned when the result of an operation is greater than MaxValue.
so your float becomes 'infinity' instead of a number.
Then, when you try an operation like divide or mod, float returns NaN. Again, from MSDN:
A method or operator returns NaN when the result of an operation is undefined.
so when you divide your float (infinity) by a number, the result is NaN
You may want to consider using BigInteger.
The following limits apply:
Float: 7 digits (32 bit)
Double: 15-16 digits (64 bit)
Decimal: 28-29 significant digits (128 bit)

Average of 3 long integers

I have 3 very large signed integers.
long x = long.MaxValue;
long y = long.MaxValue - 1;
long z = long.MaxValue - 2;
I want to calculate their truncated average. Expected average value is long.MaxValue - 1, which is 9223372036854775806.
It is impossible to calculate it as:
long avg = (x + y + z) / 3; // 3074457345618258600
Note: I read all those questions about average of 2 numbers, but I don't see how that technique can be applied to average of 3 numbers.
It would be very easy with the usage of BigInteger, but let's assume I cannot use it.
BigInteger bx = new BigInteger(x);
BigInteger by = new BigInteger(y);
BigInteger bz = new BigInteger(z);
BigInteger bavg = (bx + by + bz) / 3; // 9223372036854775806
If I convert to double, then, of course, I lose precision:
double dx = x;
double dy = y;
double dz = z;
double davg = (dx + dy + dz) / 3; // 9223372036854780000
If I convert to decimal, it works, but also let's assume that I cannot use it.
decimal mx = x;
decimal my = y;
decimal mz = z;
decimal mavg = (mx + my + mz) / 3; // 9223372036854775806
Question: Is there a way to calculate the truncated average of 3 very large integers only with the usage of long type? Don't consider that question as C#-specific, just it is easier for me to provide samples in C#.
This code will work, but isn't that pretty.
It first divides all three values (it floors the values, so you 'lose' the remainder), and then divides the remainder:
long n = x / 3
+ y / 3
+ z / 3
+ ( x % 3
+ y % 3
+ z % 3
) / 3
Note that the above sample does not always work properly when having one or more negative values.
As discussed with Ulugbek, since the number of comments are exploding below, here is the current BEST solution for both positive and negative values.
Thanks to answers and comments of Ulugbek Umirov, James S, KevinZ, Marc van Leeuwen, gnasher729 this is the current solution:
static long CalculateAverage(long x, long y, long z)
{
return (x % 3 + y % 3 + z % 3 + 6) / 3 - 2
+ x / 3 + y / 3 + z / 3;
}
static long CalculateAverage(params long[] arr)
{
int count = arr.Length;
return (arr.Sum(n => n % count) + count * (count - 1)) / count - (count - 1)
+ arr.Sum(n => n / count);
}
NB - Patrick has already given a great answer. Expanding on this you could do a generic version for any number of integers like so:
long x = long.MaxValue;
long y = long.MaxValue - 1;
long z = long.MaxValue - 2;
long[] arr = { x, y, z };
var avg = arr.Select(i => i / arr.Length).Sum()
+ arr.Select(i => i % arr.Length).Sum() / arr.Length;
Patrick Hofman has posted a great solution. But if needed it can still be implemented in several other ways. Using the algorithm here I have another solution. If implemented carefully it may be faster than the multiple divisions in systems with slow hardware divisors. It can be further optimized by using divide by constants technique from hacker's delight
public class int128_t {
private int H;
private long L;
public int128_t(int h, long l)
{
H = h;
L = l;
}
public int128_t add(int128_t a)
{
int128_t s;
s.L = L + a.L;
s.H = H + a.H + (s.L < a.L);
return b;
}
private int128_t rshift2() // right shift 2
{
int128_t r;
r.H = H >> 2;
r.L = (L >> 2) | ((H & 0x03) << 62);
return r;
}
public int128_t divideby3()
{
int128_t sum = {0, 0}, num = new int128_t(H, L);
while (num.H || num.L > 3)
{
int128_t n_sar2 = num.rshift2();
sum = add(n_sar2, sum);
num = add(n_sar2, new int128_t(0, num.L & 3));
}
if (num.H == 0 && num.L == 3)
{
// sum = add(sum, 1);
sum.L++;
if (sum.L == 0) sum.H++;
}
return sum;
}
};
int128_t t = new int128_t(0, x);
t = t.add(new int128_t(0, y));
t = t.add(new int128_t(0, z));
t = t.divideby3();
long average = t.L;
In C/C++ on 64-bit platforms it's much easier with __int128
int64_t average = ((__int128)x + y + z)/3;
You can calculate the mean of numbers based on the differences between the numbers rather than using the sum.
Let's say x is the max, y is the median, z is the min (as you have). We will call them max, median and min.
Conditional checker added as per #UlugbekUmirov's comment:
long tmp = median + ((min - median) / 2); //Average of min 2 values
if (median > 0) tmp = median + ((max - median) / 2); //Average of max 2 values
long mean;
if (min > 0) {
mean = min + ((tmp - min) * (2.0 / 3)); //Average of all 3 values
} else if (median > 0) {
mean = min;
while (mean != tmp) {
mean += 2;
tmp--;
}
} else if (max > 0) {
mean = max;
while (mean != tmp) {
mean--;
tmp += 2;
}
} else {
mean = max + ((tmp - max) * (2.0 / 3));
}
Patching Patrick Hofman's solution with supercat's correction, I give you the following:
static Int64 Avg3 ( Int64 x, Int64 y, Int64 z )
{
UInt64 flag = 1ul << 63;
UInt64 x_ = flag ^ (UInt64) x;
UInt64 y_ = flag ^ (UInt64) y;
UInt64 z_ = flag ^ (UInt64) z;
UInt64 quotient = x_ / 3ul + y_ / 3ul + z_ / 3ul
+ ( x_ % 3ul + y_ % 3ul + z_ % 3ul ) / 3ul;
return (Int64) (quotient ^ flag);
}
And the N element case:
static Int64 AvgN ( params Int64 [ ] args )
{
UInt64 length = (UInt64) args.Length;
UInt64 flag = 1ul << 63;
UInt64 quotient_sum = 0;
UInt64 remainder_sum = 0;
foreach ( Int64 item in args )
{
UInt64 uitem = flag ^ (UInt64) item;
quotient_sum += uitem / length;
remainder_sum += uitem % length;
}
return (Int64) ( flag ^ ( quotient_sum + remainder_sum / length ) );
}
This always gives the floor() of the mean, and eliminates every possible edge case.
Because C uses floored division rather than Euclidian division, it may easier to compute a properly-rounded average of three unsigned values than three signed ones. Simply add 0x8000000000000000UL to each number before taking the unsigned average, subtract it after taking the result, and use an unchecked cast back to Int64 to get a signed average.
To compute the unsigned average, compute the sum of the top 32 bits of the three values. Then compute the sum of the bottom 32 bits of the three values, plus the sum from above, plus one [the plus one is to yield a rounded result]. The average will be 0x55555555 times the first sum, plus one third of the second.
Performance on 32-bit processors might be enhanced by producing three "sum" values each of which is 32 bits long, so that the final result is ((0x55555555UL * sumX)<<32) + 0x55555555UL * sumH + sumL/3; it might possibly be further enhanced by replacing sumL/3 with ((sumL * 0x55555556UL) >> 32), though the latter would depend upon the JIT optimizer [it might know how to replace a division by 3 with a multiply, and its code might actually be more efficient than an explicit multiply operation].
If you know you have N values, can you just divide each value by N and sum them together?
long GetAverage(long* arrayVals, int n)
{
long avg = 0;
long rem = 0;
for(int i=0; i<n; ++i)
{
avg += arrayVals[i] / n;
rem += arrayVals[i] % n;
}
return avg + (rem / n);
}
You could use the fact that you can write each of the numbers as y = ax + b, where x is a constant. Each a would be y / x (the integer part of that division). Each b would be y % x (the rest/modulo of that division). If you choose this constant in an intelligent way, for example by choosing the square root of the maximum number as a constant, you can get the average of x numbers without having problems with overflow.
The average of an arbitrary list of numbers can be found by finding:
( ( sum( all A's ) / length ) * constant ) +
( ( sum( all A's ) % length ) * constant / length) +
( ( sum( all B's ) / length )
where % denotes modulo and / denotes the 'whole' part of division.
The program would look something like:
class Program
{
static void Main()
{
List<long> list = new List<long>();
list.Add( long.MaxValue );
list.Add( long.MaxValue - 1 );
list.Add( long.MaxValue - 2 );
long sumA = 0, sumB = 0;
long res1, res2, res3;
//You should calculate the following dynamically
long constant = 1753413056;
foreach (long num in list)
{
sumA += num / constant;
sumB += num % constant;
}
res1 = (sumA / list.Count) * constant;
res2 = ((sumA % list.Count) * constant) / list.Count;
res3 = sumB / list.Count;
Console.WriteLine( res1 + res2 + res3 );
}
}
I also tried it and come up with a faster solution (although only by a factor about 3/4). It uses a single division
public static long avg(long a, long b, long c) {
final long quarterSum = (a>>2) + (b>>2) + (c>>2);
final long lowSum = (a&3) + (b&3) + (c&3);
final long twelfth = quarterSum / 3;
final long quarterRemainder = quarterSum - 3*twelfth;
final long adjustment = smallDiv3(lowSum + 4*quarterRemainder);
return 4*twelfth + adjustment;
}
where smallDiv3 is division by 3 using multipliation and working only for small arguments
private static long smallDiv3(long n) {
assert -30 <= n && n <= 30;
// Constants found rather experimentally.
return (64/3*n + 10) >> 6;
}
Here is the whole code including a test and a benchmark, the results are not that impressive.
This function computes the result in two divisions. It should generalize nicely to other divisors and word sizes.
It works by computing the double-word addition result, then working out the division.
Int64 average(Int64 a, Int64 b, Int64 c) {
// constants: 0x10000000000000000 div/mod 3
const Int64 hdiv3 = UInt64(-3) / 3 + 1;
const Int64 hmod3 = UInt64(-3) % 3;
// compute the signed double-word addition result in hi:lo
UInt64 lo = a; Int64 hi = a>=0 ? 0 : -1;
lo += b; hi += b>=0 ? lo<b : -(lo>=UInt64(b));
lo += c; hi += c>=0 ? lo<c : -(lo>=UInt64(c));
// divide, do a correction when high/low modulos add up
return hi>=0 ? lo/3 + hi*hdiv3 + (lo%3 + hi*hmod3)/3
: lo/3+1 + hi*hdiv3 + Int64(lo%3-3 + hi*hmod3)/3;
}
Math
(x + y + z) / 3 = x/3 + y/3 + z/3
(a[1] + a[2] + .. + a[k]) / k = a[1]/k + a[2]/k + .. + a[k]/k
Code
long calculateAverage (long a [])
{
double average = 0;
foreach (long x in a)
average += (Convert.ToDouble(x)/Convert.ToDouble(a.Length));
return Convert.ToInt64(Math.Round(average));
}
long calculateAverage_Safe (long a [])
{
double average = 0;
double b = 0;
foreach (long x in a)
{
b = (Convert.ToDouble(x)/Convert.ToDouble(a.Length));
if (b >= (Convert.ToDouble(long.MaxValue)-average))
throw new OverflowException ();
average += b;
}
return Convert.ToInt64(Math.Round(average));
}
Try this:
long n = Array.ConvertAll(new[]{x,y,z},v=>v/3).Sum()
+ (Array.ConvertAll(new[]{x,y,z},v=>v%3).Sum() / 3);

How to calculate the modular multiplicative inverse for the Affine Cipher

I am trying to create a small software that does the Affine Cipher, which means that K1 and the amount of letters in the alphabet (using m for this number) must be coprime, that is gcd(k1, m) == 1.
Basically it's like this:
I have a plaintext: hey
I have K1: 7
I have K2: 5
Plaintext in numerical format is:
8 5 25
8 - from h (the position in the alphabet) and **
5 25** goes the same for e and y
Encrypted: 7 13 18
Which is the formula:
k1 * 8 + k2 mod 27 = 7
k1 * 5 + k2 mod 27 = 13
k1 * 25 + k2 mod 27 = 18
I have a function that crypts this but I don't know how to decrypt.
For example I have 7 for h. I want to get the number 8 back again, knowing 7, k1 and k2.
Do you guys have any ideas ?
Some function where you input k1, k2, result (7 for example, for h), and it gives me back 8, but I really don't know how to reverse this.
The function for encryption is this:
public List<int> get_crypted_char(string[] strr)
{
List<int> l = new List<int>();
int i;
for (i = 0; i < strr.Length; i++)
{
int ch = int.Parse(strr[i]);
int numberback = k1 * ch + 5;
numberback = (numberback % 27);
l.Add(numberback);
}
return l;
}
Where: string[] strr is a string that contains the plaintext.
Function example:
get_crypted_char({"e","c","b"})
The result would be a list like this {"5","3","2"}
UPDATE:
Here is a link from wikipedia about this encryption, and also decryption, but ... I don't really understand "how to"
http://en.wikipedia.org/wiki/Affine_cipher
It is not possible (in general case, for affine cipher, see update below). That's why module operation is so frequently used in security algorithms - it is not reversible. But, why don't we try?
result = (k1 * input + k2) % 27 (*1)
Let's take the first letter:
result = (7 * 8 + 5) % 27 = 7
That's cool. Now, because we said, that:
result = (k1 * input + k2) % 27
the following is also true:
k1 * input + k2 = 27 * div + result (*2)
where
div = (k1 * input + k2) / 27 (integral division)
It is quite obvious (if a % b = c, then a = b*n + c, where n is the result of integer division a/b).
You know the values of k1 (which is 7), k2 (5) and result (7). So, when we put these values to (*2), we get the following:
7 * input + 5 = 27 * div + 7 //You need to solve this
As you can see, it is impossible to solve this, because you would need to know also the result of the integral division - translating this to your function's language, you would need the value of
numberback / 27
which is unknown. So answer is: you cannot reverse your function's results, using only output it returns.
** UPDATE **
I focused too much on the question's title, so the answer above is not fully correct. I decided not to remove it, however, but write an update.
So, the answer for your particular case (affine cipher) is: YES, you can reverse it.
As you can see on the wiki, decryption function for affine cipher for the following encrytption function:
E(input) = a*input + b mod m
is defined as:
D(enc) = a^-1 * (enc - b) mod m
The only possible problem here can be computation of a^-1, which is modular multiplicative inverse.
Read about it on wiki, I will provide only example.
In your case a = k1 = 7 and m = 27. So:
7^-1 = p mod 27
7p = 1 mod 27
In other words, you need to find p, which satisfies the following: 7p % 27 = 1.
p can be computed using extended euclidean algorithm and I computed it to be 4 (4 * 7 = 28, 28 % 27 = 1).
Check, if can decipher your output now:
E(8) = 7*8 + 5 mod 27 = 7
D(7) = 4 * (7 - 5) mod 27 = 8
Hope that helps :)
Please note that the other answers do not take into account the the algorithm at hand is the Affine Cipher, ie there are some conditions at hand, the most important one the coprime status of k1 and m.
In your case it would be:
m = 27; // letters in your alphabet
k1 = 7; // coprime with m
k2 = 5; // no reqs here, just that a value above 27 is the same as mod 27 of that value
int Encrypt(int letter) {
return ((letter * k1) + k2) % m;
}
int Decrypt(int letter) {
return ((letter - k2) * modInverse(k1, m)) % m;
}
Tuple<int, Tuple<int, int>> extendedEuclid(int a, int b)
{
int x = 1, y = 0;
int xLast = 0, yLast = 1;
int q, r, m, n;
while (a != 0)
{
q = b / a;
r = b % a;
m = xLast - q * x;
n = yLast - q * y;
xLast = x; yLast = y;
x = m; y = n;
b = a; a = r;
}
return new Tuple<int, Tuple<int, int>>(b, new Tuple<int, int>(xLast, yLast));
}
int modInverse(int a, int m)
{
return (extendedEuclid(a, m).Item2.Item1 + m) % m;
}
ModInverse implementation taken from http://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse/.
I have created a program that will tell the modular inverse of something. I will let you use it. It is posted below.
# Cryptomath Module
def gcf(a, b):
# Return the GCD of a & b using Euclid's Algorithm
while a != 0:
a, b = b % a, a
return b
def findModInverse(a, m):
# Return the modular inverse of a % m, which is
# the number x such that a*x % m = 1
if gcf(a, m) != 1:
return None # No mode inverese if a & m aren't relatively prime
# Calculate using the Extended Euclidean Algorithm:
u1, u2, u3 = 1, 0, a
v1, v2, v3 = 0, 1, m
while v3 != 0:
q = u3 // v3 # // is the integer division operator
v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q *
v3), v1, v2, v3
return u1 % m
Note: The modular inverse is found using the extended euclidean algorithm. Here is the Wikipedia entry for it: http://en.wikipedia.org/wiki/Extended_Euclidean_algorithm.
Note: This needs to be imported as a module to be used. Hope it helps.

Categories

Resources