How to encrypt an ASCII character with textbook RSA in C#? - c#

I have a problem with calculate of ASCII value with exponent and modulus.
I want calculate ASCII value of "K" with RSA algorithm.
K in ascii value is 75
c = m^e mod n
= 75^41 mod 689
= 316
Then how to make it into source code in C#? I got error "cannot implicity convert type".
this my source code
int n = 689;
int e = 41;
int d = 137;
string value = "K";
for (int i = 0; i < value.Length; i++)
{
int c = (int)i;
c = Math.Pow(i,e);
}
Console.ReadLine();

Since 75^41 will overflow if cast to an int you have to do a little math trick. A*B mod N is equivalent to (A mod N) * (B mod N) mod N, so you just do the multiplication in a loop, taking the remainder each time:
public static int PowModN(int a, int b, int n)
{
a = a % n;
int c = 1;
for(int i=1; i <= b; i++)
c = (c*a % n);
return c;
}
and change your loop to:
for (int i = 0; i < value.Length; i++)
{
int c = (int)i;
c = PowModN(i,e,n);
}

string value = "K";
// Convert the string into a byte[].
byte[] asciiBytes = Encoding.ASCII.GetBytes(value);
Once you get the array out put you can set it to a variable and do whatever math you need to do.

The output of Math.Pow is a double, and takes two floats as arguments. At the very least, cast the output of Math.Pow(i,e) to be an int, like so:
c = (int)Math.Pow(i,e)
This is one of the worst things about C#, imo. Not sure why it doesn't innately support integer exponentiation.
What type is i? It might need to be casted to doubles as well.

Related

C# char Conversion/Append to/with int, int64, string

Lately I have been working through Project Euler, specifically
https://projecteuler.net/problem=4
I create to arrays
Multiply them together
Convert the number in a CharArry
Compare the numbers
If true, my problem arises
I attempt to convert the char back to an int, or long, or string,
and
I have attempted to append the char to an int, or long, or string, or whatever
void Main()
{
int[] arrOne = new int[900]; // Initializing Array One
int[] arrTwo = new int[900]; // Initializing Array Two
Console.WriteLine(PopulateAndConvert(arrOne, arrTwo)); // Sending info into class
}
int PopulateAndConvert(int[] a, int[] b)
{
char[] c = new char[1]; // char used to store tested number
//string[] m = new string[a.Length*b.Length];
long l = 0; // Used for testing code
for(int i = 0; i < a.Length; i++) // Populating Arrays One and Two
{
a[i] = i + 100;
b[i] = i + 100;
}
for(int j = a.Length-1; j >= 0; j--) // Beginning for-loops for multiplication and testing
{
//Console.WriteLine(j);
for(int k = b.Length-1; k >= 0; k--) // Second part of for-loop previously mentioned
{
//Console.WriteLine(k);
c = (a[j] * b[k]).ToString().ToCharArray(); // Where the math and conversion happens
//Console.WriteLine(c);
if(c.Length > 5) // Checking if digit of product is greater than 5
{
if((c[0] == c[c.Length-1]) && // Comparing first and second half of product
(c[1] == c[c.Length-2]) &&
(c[2] == c[c.Length-3]))
{
/*for(int n = 0; n < c.Length; n++) // Last tidbit of code that was being attempted
sb[l].Append(Convert.ToInt32(c[0]));
l++;
Console.WriteLine(sb); */
}
}
else if (c.Length < 5) // Product with less than 6 digits go here
{
if((Convert.ToInt32(c[0]) == Convert.ToInt32(c[4])) &&
(Convert.ToInt32(c[1]) == Convert.ToInt32(c[3])))
{
//m[l] = Convert.ToChar(c); l++;
}
}
}
}
// Everything below was used to check the code that I have been trying to work through
// And to place the given products in a ascending or descending order
//foreach (char x in m)
// Console.WriteLine(m);
//IEnumerable<char> sortDescendingQuery =
// from num in c
// orderby num descending
// select num;
return 0;
}
After some time (resting the mind is always beneficial) I found a solution:
if(c.Length > 5) // Checking if digit of product is greater than 5
{
int[] n = new int[c.Length];
StringBuilder sb = new StringBuilder();
if((c[0] == c[c.Length-1]) && // Comparing first and second half of product
(c[1] == c[c.Length-2]) &&
(c[2] == c[c.Length-3]))
{
for(int l = 0; l < c.Length; l++) // Converting each value in the char array to a stringbuilder
{
sb.Append(Convert.ToInt32(new string(c[l], 1)));
}
m[q] = Int32.Parse(sb.ToString()); // Converting stringbuilder into string and then into a long
q++;
}
}
I had to convert each individual value within the char array c[] to a string, then an int, then append it to the string builder sb.
After that I then convert sb to a string (via ToString()) and Parse it to an int.
It seems like a long work around, but it works.
Now I need to Sort it numerically (another hurdle).

Reverse binary representation of int (only significant bits)

I'm trying to write a program for reversing numbers in binary. For instance, the binary representation of 13 is 1101, and reversing it gives 1011, which corresponds to number 11 right?
Here's my code:
static void Main(string[] args)
{
Console.WriteLine("Enter a Number");
int numb = int.Parse(Console.ReadLine());
int reverse = 0;
while (numb > 0)
{
int rem = numb % 10;
reverse = (reverse * 10) + rem;
numb = numb / 10;
}
Console.WriteLine("Reverse number={0}", reverse);
Console.ReadLine();
}
By this code I only get the numbers to reverse (13 -> 31)...
The input should contain a single line with an integer N, 1≤N≤1000000000 and I want my output in one line with one integer, the number I want to get by reversing the binary representation of N.
Something like that
// 13 = 1101b
int value = 13;
// 11 = 1011b
int result = Convert.ToInt32(new String(
Convert.ToString(value, 2)
.Reverse()
.ToArray()), 2);
Explanation:
Convert.ToString(value, 2) returns value in binary representation ("1101")
Reverse().ToArray() - reverse the string ('1','0','1','1') as sequence of characters and converts to array char[].
new String(...) constructs string "1011" from array of char
finally, Convert.ToInt32(..., 2) convert binary representation back to int
You can use Convert.ToString and Convert.ToInt32 methods, where 2 means binary:
int numb = int.Parse(Console.ReadLine());
var reversedString = Convert.ToString(numb, 2).ReverseString();
var result = Convert.ToInt32(reversedString, 2);
...
public static string ReverseString(this string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
A fun excercise would be doing this without using the string conversion.
I have very little experience with bit twiddling so there is probably a faster and better way of doing this, but this seems to work:
public static IEnumerable<bool> ToBinary(this int n)
{
for (int i = 0; i < 32; i++)
{
yield return (n & (1 << i)) != 0;
}
}
public static int ToInt(this IEnumerable<bool> b)
{
var n = 0;
var counter = 0;
foreach (var i in b.Trim().Take(32))
{
n = n | (i ? 1 : 0) << counter;
counter++
}
return n;
}
private static IEnumerable<bool> Trim(this IEnumerable<bool> list)
{
bool trim = true;
foreach (var i in list)
{
if (i)
{
trim = false;
}
if (!trim)
{
yield return i;
}
}
}
And now you'd call it like this:
var reversed = n.ToBinary().Reverse().ToInt();

How do I find the palindrome of a number?

I already wrote the part of the program that reverses the number:
int n = 0;
n = Convert.ToInt32(textBox1.Text);
double l = n;
double reverse = 0;
while (left > 0)
{
double r = left % 10;
reverse = reverse * 10 + r;
l = l / 10;
}
double final = n + rev;
However, if the final double does is not a palindrome, I want the program to add the final to its palindrome, and keep doing that until the a palindrome is found. The problem is in the the conditional statement.What condition should I give to the if statement?
I think you can just reverse the string rather than treat it as a number:
using System.Linq;
var N = textBox1.Text;
var reversedN = new string(n.Reverse().ToArray());
var result = Convert.ToInt32(reversedN);
As in this thread
bool isPalindrome(String s)
{
char[] charArray = s.ToCharArray();
Array.Reverse( charArray );
return s.equals(new string(charArray));
}
Do the palindrome check on the string. If it's not a palindrome, convert the string to an int, add whatever you want, convert it back to a string, repeat.
Avoid working with double in this application. Stick to int.

How to get the maximum number of a particular length

I have a number, for example 1234567897865; how do I max it out and create 99999999999999 ?
I did this this way:
int len = ItemNo.ToString().Length;
String maxNumString = "";
for (int i = 0; i < len; i++)
{
maxNumString += "9";
}
long maxNumber = long.Parse(maxNumString);
what would be the better, proper and shorter way to approach this task?
var x = 1234567897865;
return Math.Pow(10, Math.Ceiling(Math.Log10(x+1e-6))) - 1;
To expand on comments below, if this problem was expressed in hex or binary, it could be done very simply using shift operators
i.e., "I have a number, in hex,, for example 3A67FD5C; how do I max it out and create FFFFFFFF?"
I'd have to play with this to make sure it works exactly, but it would be something like this:
var x = 0x3A67FD5C;
var p = 0;
while((x=x>>1)>0) p++; // count how many binary values are in the number
return (1L << 4*(1+p/4)) - 1; // using left shift, generate 2 to
// that power and subtract one
long maxNumber = long.Parse(new String('9', ItemNo.ToString().Length));
Try this:
int v = 1;
do {
v = v * 10;
} while (v <= number);
return v - 1;
int numDigits = (int)Math.Ceiling(Math.Log10(number));
int result = (int)(Math.Pow(10, numDigits) - 1)
I don't have a compiler available at the moment, so some additional string/double conversions may need to happen here.

how to get all permutations for bitarray

how to generate all permutations for bitarray of n size?
I mean for example if array of 1 and 0 has integer type I can do like this
for (int i = 0; i <= ~(-1 << n); i++)
string s = Convert.ToString(i, 2).PadLeft(n, '0');
and s will contain some permutation for example 101010 or 100000 and etc.
So I can get all permutations.
For example for n=3
000
001
010
011
100
101
110
111
But how to do the same for bitarray?(because I need XOR operations and etc.)
I don't have VS open right now, but you could use the BitArray(byte[]) constructor.
for (var i = 0; i < 1 << n; i++)
{
byte[] bytes = BitConverter.GetBytes(i);
var bitArray = new BitArray(bytes);
}
You'll have to experiment and come up with the shifting logic to convert an int into bytes.
If you need greater than 32/64 bits, then you'll obviously need another approach.
Why don't you work with int or long , since you will never able to work with permutations larger than ~2^32(in fact much lesser) in a reasonable time.
for (int i = 0; i < 64; i++)
{
Console.WriteLine(Convert.ToString(i,2).PadLeft(6,'0'));
}
Output:
000000
000001
000010
000011
000100
000101
000110
000111
001000
001001
001010
001011
001100
etc.
This is based on a recursive list-filling procedure that I wrote for a recent project.
private void GenerateStringsRecursive(List<string> strings, int n, string cur)
{
if (cur.Length == n)
{
strings.Add(cur);
}
else
{
GenerateStringsRecursive(strings, n, cur + "0");
GenerateStringsRecursive(strings, n, cur + "1");
}
}
Call it like this:
List<string> strings = new List<string>();
GenerateStringsRecursive(strings, n, "");
foreach (string s in strings)
{
Console.WriteLine(s);
}
I imagine this would be subject to optimizations such as using a StringBuilder etc.
A generalised Permute function that will return all the combinations of any enumerable.
public static IEnumerable<IEnumerable<T>> Permute<T>(this IEnumerable<T> list)
{
for (int i = (1 << list.Count()) - 1; i >= 0; i--)
yield return list.BitWhere(i);
}
public static IEnumerable<T> BitWhere<T>(this IEnumerable<T> list, int selector)
{
BitVector32 bits = new BitVector32(selector);
int c = list.Count();
for (int i = 1; i <= c; i++)
{
if (bits[1 << (c - i)])
yield return list.ElementAt(i - 1);
}
}
You can use BigInteger for this task.
It is essentially a bit array with arithmetic operations, so you can permute the bits by adding one, as you already can do with Int32 and Int64 integers.
At the same time, BigInteger supports bit arithmetics, so you can do xor with ^ operator.

Categories

Resources