Хэш код - C#
Формулировка задачи:
Добрый вечер, попался дипломный проект на тему составления программы для расчет хэш кода, c# я в принципе знаю очень поверхностно, но программу составил, нужна помощь, возможно как то код можно оптимизировать, сократить. По возможности закомментил и условия в принципе такое: Дается любое слово, которое мы раскладываем согласно ASCII коду, к примеру HASHING - 72 65 83 72 73 78 71, переводить в двоичный вид, 01001000 01000001 и т.д, разделяем число на две части и подставляем по 1111 - М1 = 111101000, М2 = 11111000, М3 = 11110100, М = 11110001 и т.д. и далее начинаем производить расчет, М1 + Н0(00000000) в 10ом виде = 244, и конечная формула: ((H0+M1)^2)*(mod323), (323 число задается вручную). И так повторяем до конца. Сложность была ещё в том что таблица ASCII найденная в интернета, и актуальная на учебе, немного различается, пришлось вносить корректировки.
Сам код.
В заранее спасибо, учту любые замечания. В принципе она и так работает отлично, но хотелось бы знать что можно упростить.
{
origin:
string s;
long ne;
Console.WriteLine("Введите кодируемое слово");
s = Console.ReadLine();
Console.WriteLine("Укажите значение n");
ne = Convert.ToInt32(Console.ReadLine()); //получаем число n
Console.WriteLine();
int length = s.Length;
byte[] bytes = Encoding.GetEncoding(1251).GetBytes(s); //Получаем ASCII код
int[] vich = new int[length];
int[] f = new int[length];
string[] F = new string[length];
for (int i = 0; i < length; i++) //Выполнение условия, чтобы совпала таблица кодов с той которой необходимо.
{
if (bytes[i] < 240)
{
if (bytes[i] > 127)
{
vich[i] = bytes[i] - 64;
f[i] = Convert.ToInt32(vich[i]);
}
else
{
vich[i] = bytes[i];
f[i] = Convert.ToInt32(vich[i]);
}
}
else
{
vich[i] = bytes[i] - 16;
f[i] = Convert.ToInt32(vich[i]);
}
Console.WriteLine("{0} = {1}", s[i],vich[i]);
}
//конец 1 блока
for (int i = 0; i < length; i++)
{
F[i] = Convert.ToString(f[i], 2).PadLeft(8, '0'); //Добавляем бит если его недостаточно до 8
}
//Начало подсчета Мок
int Mka, N1, N2, N3, N4, N5, N6, x = 0, ye = 0, o = 0, p = 0;
string[] N = new string[length * 3];
string[] M = new string[length * 3];
int rashet = 1;
string n1, n2, mka = "11110000";
Console.WriteLine();
for (int i = 0; i < length; i++)
{
ye = x + ++x;
o = p + p++;
string buk = F[i];
Mka = Convert.ToInt32(mka, 2);
N1 = Convert.ToInt32(buk) % Convert.ToInt32(Math.Pow(10, Convert.ToString(buk).Length / 2)); //Первая часть битов
N2 = Convert.ToInt32(buk) / Convert.ToInt32(Math.Pow(10, Convert.ToString(buk).Length / 2)); //Вторая часть битов
n2 = Convert.ToString(N2);
n1 = Convert.ToString(N1);
N5 = Convert.ToInt32(n1, 2);
N6 = Convert.ToInt32(n2, 2);
N3 = Mka ^ N5; //Биты подставляются после 1111хххх
N4 = Mka ^ N6;
N[o] = Convert.ToString(N4, 2);
N[ye] = Convert.ToString(N3, 2);
Console.WriteLine("M{1} = {0}\tM{3} = {2}\n", N[o], rashet++, N[ye], rashet++);
}
//Начало подсчета H
long num, Result;
Console.WriteLine();
string H0 = "00000000", M1;
int t1, t2, hn;
double[] yd = new double[length * 3];
double YD;
long[] er = new long[length * 3];
int[] T1 = new int[length * 3];
int[] H = new int[length * 3];
int[] A = new int[length * 3];
long[] B = new long[length * 3];
long[] res = new long[length * 3];
int[] mod = new int[length * 3];
string[] Mod = new string[length * 3];
int[] T2 = new int[length * 3];
int u = 0, v = 0, q = 0, w = 0, pls;
t1 = Convert.ToInt32(N[0], 2);
Console.WriteLine("N = {0}" ,N[0]);
t2 = Convert.ToInt32(H0, 2);
hn = t1 ^ t2;
M1 = Convert.ToString(hn);
num = Convert.ToInt32(M1);
num = Convert.ToInt32(Math.Pow(num, 2)); //Число из степени
Math.DivRem(num, ne, out Result); //Остаток от деления
pls = Convert.ToInt32(Result);
N[0] = Convert.ToString(Result, 2);
YD = Convert.ToDouble(N[0]);
Console.WriteLine(" H1 =\t{0:#,###}\t({1})\tM1+H0 =\t{2}", YD, pls, hn);
length = length * 2;
for (int i = 1, r = 0; i < length; i++, r++) //Расчет всех H
{
q = w + ++w;
u = v + v++;
T1[i] = Convert.ToInt32(N[i], 2);//M в десятичном
T2[i] = Convert.ToInt32(pls);//H в десятичном
mod[i] = T1[i] ^ T2[i];
Mod[i] = Convert.ToString(mod[i]);
B[i] = Convert.ToInt32(Mod[i]);
er[i] = Convert.ToInt32(Math.Pow(B[i], 2));
Math.DivRem(er[i], ne, out res[i]);
pls = Convert.ToInt32(res[i]);
N[i] = Convert.ToString(pls, 2);
yd[i] = Convert.ToDouble(N[i]);
Console.WriteLine(" H{1} =\t{0:#,###}\t({2})\tM{1}+H{4} = {3}", yd[i], i + 1, pls, B[i], i);
}
Console.WriteLine();
ConsoleKeyInfo cki;
Console.WriteLine("Для повтора нажмите ESC \n");
do
{
cki = Console.ReadKey();
}
while (cki.Key != ConsoleKey.Escape);
Console.Clear();
goto origin;
}Решение задачи: «Хэш код»
textual
Листинг программы
using System;
using System.Text;
namespace ConsoleApplication198
{
internal class Program
{
static void Main(string[] args)
{
do
{
Console.Clear();
Console.WriteLine("Введите кодируемое слово");
var str = Console.ReadLine();
Console.WriteLine("Укажите значение n");
var n = int.Parse(Console.ReadLine()); //получаем число n
Console.WriteLine();
var hash = GetHashCode(str, n);
Console.WriteLine("Result hash: {0}\r\n", hash);
Console.WriteLine("Для выхода нажмите ESC, для повтора - любую другую клавишу");
}
while (Console.ReadKey().Key != ConsoleKey.Escape);
}
static byte GetHashCode(string str, int divider)
{
var bytes = Encoding.GetEncoding(1251).GetBytes(str);
var hash = (byte)0;
foreach(var b in bytes)
{
var left = (byte)(b >> 4);//берем левые 4 бита
GetHashCode(left, divider, ref hash);
var right = (byte)(b & 0x0F);//берем правые 4 бита
GetHashCode(right, divider, ref hash);
}
return hash;
}
static void GetHashCode(byte m, int divider, ref byte h)
{
m = (byte)(m + 0xF0);//добавляем 11110000
Console.Write("M: {0} ", ToBin(m));
m = (byte)(m ^ h);//сложение по модулю два с хешем
Console.Write("M ^ H: {0} ", ToBin(m));
h = (byte)((m * m) % divider);//возводим в квадрат и берем модуль по основанию divider
Console.WriteLine("H: {0}", ToBin(h));
}
//преобразование в строку в бинарном формате, для вывода на экран
static string ToBin(int v)
{
return Convert.ToString(v, 2).PadLeft(8, '0');
}
}
}