Forum: PC-Programmierung NTLM Algorithmus in C#


von Sebastian N. (sebastian_neusch)


Lesenswert?

Hallo an alle,

ich habe schon for einem Jahr einen Thread eröffnet([[Wo gibt es eine 
gute Hashfunktion für NTLM (C#)]]) in Bezug auf einen NTLM-Algorithmus, 
jedoch gab dieser mir keine klare Antwort, da ich nicht herausgefunden 
habe wie der Algorithmus wirklich aufgebaut ist und ich es immer noch 
nicht geschafft habe das C Code Snippet in C# zu übersetzen.

Entschuldigt dass ich nochmal nen Thread aufmach aber ich dachte der 
alte ist zu alt.

Mein Problem ist dass ich mich auch mit den ganzen uint Typen nicht 
wirklich auskenne und es dabei zu ziemlich viel "Murks" beim übersetzen 
kam.
Hier nochmal der C-Code:
1
#include <string.h>
2
#include <stdio.h>
3
 
4
//Init values
5
#define INIT_A 0x67452301
6
#define INIT_B 0xefcdab89
7
#define INIT_C 0x98badcfe
8
#define INIT_D 0x10325476
9
 
10
#define SQRT_2 0x5a827999
11
#define SQRT_3 0x6ed9eba1
12
 
13
unsigned int nt_buffer[16];
14
unsigned int output[4];
15
char hex_format[33];
16
char itoa16[17] = "0123456789ABCDEF";
17
 
18
//This is the MD4 compress function
19
static void ntlm_crypt()
20
{
21
  unsigned int a = INIT_A;
22
  unsigned int b = INIT_B;
23
  unsigned int c = INIT_C;
24
  unsigned int d = INIT_D;
25
 
26
  /* Round 1 */
27
  a += (d ^ (b & (c ^ d)))  +  nt_buffer[0]  ;a = (a << 3 ) | (a >> 29);
28
  d += (c ^ (a & (b ^ c)))  +  nt_buffer[1]  ;d = (d << 7 ) | (d >> 25);
29
  c += (b ^ (d & (a ^ b)))  +  nt_buffer[2]  ;c = (c << 11) | (c >> 21);
30
  b += (a ^ (c & (d ^ a)))  +  nt_buffer[3]  ;b = (b << 19) | (b >> 13);
31
 
32
  a += (d ^ (b & (c ^ d)))  +  nt_buffer[4]  ;a = (a << 3 ) | (a >> 29);
33
  d += (c ^ (a & (b ^ c)))  +  nt_buffer[5]  ;d = (d << 7 ) | (d >> 25);
34
  c += (b ^ (d & (a ^ b)))  +  nt_buffer[6]  ;c = (c << 11) | (c >> 21);
35
  b += (a ^ (c & (d ^ a)))  +  nt_buffer[7]  ;b = (b << 19) | (b >> 13);
36
 
37
  a += (d ^ (b & (c ^ d)))  +  nt_buffer[8]  ;a = (a << 3 ) | (a >> 29);
38
  d += (c ^ (a & (b ^ c)))  +  nt_buffer[9]  ;d = (d << 7 ) | (d >> 25);
39
  c += (b ^ (d & (a ^ b)))  +  nt_buffer[10] ;c = (c << 11) | (c >> 21);
40
  b += (a ^ (c & (d ^ a)))  +  nt_buffer[11] ;b = (b << 19) | (b >> 13);
41
 
42
  a += (d ^ (b & (c ^ d)))  +  nt_buffer[12] ;a = (a << 3 ) | (a >> 29);
43
  d += (c ^ (a & (b ^ c)))  +  nt_buffer[13] ;d = (d << 7 ) | (d >> 25);
44
  c += (b ^ (d & (a ^ b)))  +  nt_buffer[14] ;c = (c << 11) | (c >> 21);
45
  b += (a ^ (c & (d ^ a)))  +  nt_buffer[15] ;b = (b << 19) | (b >> 13);
46
 
47
  /* Round 2 */
48
  a += ((b & (c | d)) | (c & d)) + nt_buffer[0] +SQRT_2; a = (a<<3 ) | (a>>29);
49
  d += ((a & (b | c)) | (b & c)) + nt_buffer[4] +SQRT_2; d = (d<<5 ) | (d>>27);
50
  c += ((d & (a | b)) | (a & b)) + nt_buffer[8] +SQRT_2; c = (c<<9 ) | (c>>23);
51
  b += ((c & (d | a)) | (d & a)) + nt_buffer[12]+SQRT_2; b = (b<<13) | (b>>19);
52
 
53
  a += ((b & (c | d)) | (c & d)) + nt_buffer[1] +SQRT_2; a = (a<<3 ) | (a>>29);
54
  d += ((a & (b | c)) | (b & c)) + nt_buffer[5] +SQRT_2; d = (d<<5 ) | (d>>27);
55
  c += ((d & (a | b)) | (a & b)) + nt_buffer[9] +SQRT_2; c = (c<<9 ) | (c>>23);
56
  b += ((c & (d | a)) | (d & a)) + nt_buffer[13]+SQRT_2; b = (b<<13) | (b>>19);
57
 
58
  a += ((b & (c | d)) | (c & d)) + nt_buffer[2] +SQRT_2; a = (a<<3 ) | (a>>29);
59
  d += ((a & (b | c)) | (b & c)) + nt_buffer[6] +SQRT_2; d = (d<<5 ) | (d>>27);
60
  c += ((d & (a | b)) | (a & b)) + nt_buffer[10]+SQRT_2; c = (c<<9 ) | (c>>23);
61
  b += ((c & (d | a)) | (d & a)) + nt_buffer[14]+SQRT_2; b = (b<<13) | (b>>19);
62
 
63
  a += ((b & (c | d)) | (c & d)) + nt_buffer[3] +SQRT_2; a = (a<<3 ) | (a>>29);
64
  d += ((a & (b | c)) | (b & c)) + nt_buffer[7] +SQRT_2; d = (d<<5 ) | (d>>27);
65
  c += ((d & (a | b)) | (a & b)) + nt_buffer[11]+SQRT_2; c = (c<<9 ) | (c>>23);
66
  b += ((c & (d | a)) | (d & a)) + nt_buffer[15]+SQRT_2; b = (b<<13) | (b>>19);
67
 
68
  /* Round 3 */
69
  a += (d ^ c ^ b) + nt_buffer[0]  +  SQRT_3; a = (a << 3 ) | (a >> 29);
70
  d += (c ^ b ^ a) + nt_buffer[8]  +  SQRT_3; d = (d << 9 ) | (d >> 23);
71
  c += (b ^ a ^ d) + nt_buffer[4]  +  SQRT_3; c = (c << 11) | (c >> 21);
72
  b += (a ^ d ^ c) + nt_buffer[12] +  SQRT_3; b = (b << 15) | (b >> 17);
73
 
74
  a += (d ^ c ^ b) + nt_buffer[2]  +  SQRT_3; a = (a << 3 ) | (a >> 29);
75
  d += (c ^ b ^ a) + nt_buffer[10] +  SQRT_3; d = (d << 9 ) | (d >> 23);
76
  c += (b ^ a ^ d) + nt_buffer[6]  +  SQRT_3; c = (c << 11) | (c >> 21);
77
  b += (a ^ d ^ c) + nt_buffer[14] +  SQRT_3; b = (b << 15) | (b >> 17);
78
 
79
  a += (d ^ c ^ b) + nt_buffer[1]  +  SQRT_3; a = (a << 3 ) | (a >> 29);
80
  d += (c ^ b ^ a) + nt_buffer[9]  +  SQRT_3; d = (d << 9 ) | (d >> 23);
81
  c += (b ^ a ^ d) + nt_buffer[5]  +  SQRT_3; c = (c << 11) | (c >> 21);
82
  b += (a ^ d ^ c) + nt_buffer[13] +  SQRT_3; b = (b << 15) | (b >> 17);
83
 
84
  a += (d ^ c ^ b) + nt_buffer[3]  +  SQRT_3; a = (a << 3 ) | (a >> 29);
85
  d += (c ^ b ^ a) + nt_buffer[11] +  SQRT_3; d = (d << 9 ) | (d >> 23);
86
  c += (b ^ a ^ d) + nt_buffer[7]  +  SQRT_3; c = (c << 11) | (c >> 21);
87
  b += (a ^ d ^ c) + nt_buffer[15] +  SQRT_3; b = (b << 15) | (b >> 17);
88
 
89
  output[0] = a + INIT_A;
90
  output[1] = b + INIT_B;
91
  output[2] = c + INIT_C;
92
  output[3] = d + INIT_D;
93
}  
94
 
95
//This include the Unicode conversion and the padding
96
static void prepare_key(char *key)
97
{
98
  int i=0;
99
  int length=strlen(key);
100
  memset(nt_buffer,0,16*4);
101
  //The length of key need to be <= 27
102
  for(;i<length/2;i++)  
103
    nt_buffer[i] = key[2*i] | (key[2*i+1]<<16);
104
 
105
  //padding
106
  if(length%2==1)
107
    nt_buffer[i] = key[length-1] | 0x800000;
108
  else
109
    nt_buffer[i]=0x80;
110
  //put the length
111
  nt_buffer[14] = length << 4;
112
}
113
 
114
//This convert the output to hexadecimal form
115
static void convert_hex()
116
{
117
  int i=0;
118
  //Iterate the integer
119
  for(;i<4;i++)
120
  {
121
    int j=0;
122
    unsigned int n=output[i];
123
    //iterate the bytes of the integer    
124
    for(;j<4;j++)
125
    {
126
      unsigned int convert=n%256;
127
      hex_format[i*8+j*2+1]=itoa16[convert%16];
128
      convert=convert/16;
129
      hex_format[i*8+j*2+0]=itoa16[convert%16];
130
      n=n/256;
131
    }  
132
  }
133
  //null terminate the string
134
  hex_format[33]=0;
135
}

von Michael (Gast)


Lesenswert?

Sebastian N. schrieb:
> Mein Problem ist dass ich mich auch mit den ganzen uint Typen nicht
> wirklich auskenne und es dabei zu ziemlich viel "Murks" beim übersetzen
> kam.

Und nun? Sollen wir dir den Code zeilenweise erklären?

Wie wärs, wenn du mal konkrete Fragen stellen würdest?

von Dennis S. (eltio)


Lesenswert?

"Murks" lässt sich bestimmt auch genauer definieren, oder?

von Sebastian N. (sebastian_neusch)


Lesenswert?

Wär toll wenn mir das jemand in ne bibliothek kompilieren könnte oder 
sich jemand meine übersetzung des code stücks angucken könnte

von Dennis S. (eltio)


Lesenswert?

Wie lautet deine Compiler-Ausgabe?

von Borislav B. (boris_b)


Lesenswert?

Mal ehrlich: dieses Stück C/C++ Code lässt sich doch fast 1 zu 1 in C# 
übersetzen. Dafür sind die Sprachen syntaxmäßig ja verwand genug.

Dann einfach mal kompilieren. Anhand der Compilerfehler findest du die 
verbliebenen Syntax-Probleme ja ziemlich schnell.

Danach lässt du beide Programme mal mit dem gleichen Input und einem 
Debugger Schritt für Schritt nebeneinander laufen, und schaust dir die 
Zwischenergebnisse an. Wenn sich dein C# Programm dann anders verhalten 
sollte, findest du das so ganz schnell heraus.

Am Ende hast du dann dein sematisch äquivalentes C# Programm.

: Bearbeitet durch User
von Sebastian N. (sebastian_neusch)


Lesenswert?

Hier ist mal mein Übersetzter:
1
#define INIT_A
2
#define INIT_B
3
#define INIT_C
4
#define INIT_D
5
#define SQRT_2
6
#define SQRT_3
7
using System;
8
using System.Text;
9
10
11
12
namespace NTLM
13
{
14
    class _NTLM
15
    {
16
        private static uint[] nt_buffer = new uint[16];
17
        private static uint[] output = new uint[4];
18
        private static char[] hex_format = new char[34];
19
        public static string result = "";
20
        private static string itoa16 = "0123456789abcdef";
21
        //*************************************************************** 
22
23
        public static void NTLM(string key)
24
        {
25
            int i = 0;
26
            int length = key.Length;
27
            
28
            //memset(nt_buffer, 0, 16 * 4);
29
          for(int z = 0; z < nt_buffer.Length; z++)
30
          {
31
            nt_buffer[z] = 16 * 4;
32
          }
33
            //The length of key need to be <= 27
34
            for (; i < length / 2; i++)
35
            {
36
                nt_buffer[i] = Convert.ToUInt32(key[2 * i] | (key[2 * i + 1] << 16));
37
            }
38
            if (length % 2 == 1)
39
            {
40
                nt_buffer[i] = Convert.ToUInt32(key[length - 1] | 0x800000);
41
            }
42
            else
43
            {
44
                nt_buffer[i] = 0x80;
45
            }
46
            //put the length
47
            nt_buffer[14] = Convert.ToUInt32(length << 4);
48
            uint a = DefineConstants.INIT_A;
49
            uint b = Convert.ToUInt32(DefineConstants.INIT_B);
50
            uint c = Convert.ToUInt32(DefineConstants.INIT_C);
51
            uint d = DefineConstants.INIT_D;
52
            
53
            /* Round 1 */
54
            a += (d ^ (b & (c ^ d))) + nt_buffer[0]; a = (a << 3) | (a >> 29);
55
            d += (c ^ (a & (b ^ c))) + nt_buffer[1]; d = (d << 7) | (d >> 25);
56
            c += (b ^ (d & (a ^ b))) + nt_buffer[2]; c = (c << 11) | (c >> 21);
57
            b += (a ^ (c & (d ^ a))) + nt_buffer[3]; b = (b << 19) | (b >> 13);
58
59
            a += (d ^ (b & (c ^ d))) + nt_buffer[4]; a = (a << 3) | (a >> 29);
60
            d += (c ^ (a & (b ^ c))) + nt_buffer[5]; d = (d << 7) | (d >> 25);
61
            c += (b ^ (d & (a ^ b))) + nt_buffer[6]; c = (c << 11) | (c >> 21);
62
            b += (a ^ (c & (d ^ a))) + nt_buffer[7]; b = (b << 19) | (b >> 13);
63
64
            a += (d ^ (b & (c ^ d))) + nt_buffer[8]; a = (a << 3) | (a >> 29);
65
            d += (c ^ (a & (b ^ c))) + nt_buffer[9]; d = (d << 7) | (d >> 25);
66
            c += (b ^ (d & (a ^ b))) + nt_buffer[10]; c = (c << 11) | (c >> 21);
67
            b += (a ^ (c & (d ^ a))) + nt_buffer[11]; b = (b << 19) | (b >> 13);
68
69
            a += (d ^ (b & (c ^ d))) + nt_buffer[12]; a = (a << 3) | (a >> 29);
70
            d += (c ^ (a & (b ^ c))) + nt_buffer[13]; d = (d << 7) | (d >> 25);
71
            c += (b ^ (d & (a ^ b))) + nt_buffer[14]; c = (c << 11) | (c >> 21);
72
            b += (a ^ (c & (d ^ a))) + nt_buffer[15]; b = (b << 19) | (b >> 13);
73
74
            /* Round 2 */
75
            a += ((b & (c | d)) | (c & d)) + nt_buffer[0] + DefineConstants.SQRT_2; a = (a << 3) | (a >> 29);
76
            d += ((a & (b | c)) | (b & c)) + nt_buffer[4] + DefineConstants.SQRT_2; d = (d << 5) | (d >> 27);
77
            c += ((d & (a | b)) | (a & b)) + nt_buffer[8] + DefineConstants.SQRT_2; c = (c << 9) | (c >> 23);
78
            b += ((c & (d | a)) | (d & a)) + nt_buffer[12] + DefineConstants.SQRT_2; b = (b << 13) | (b >> 19);
79
80
            a += ((b & (c | d)) | (c & d)) + nt_buffer[1] + DefineConstants.SQRT_2; a = (a << 3) | (a >> 29);
81
            d += ((a & (b | c)) | (b & c)) + nt_buffer[5] + DefineConstants.SQRT_2; d = (d << 5) | (d >> 27);
82
            c += ((d & (a | b)) | (a & b)) + nt_buffer[9] + DefineConstants.SQRT_2; c = (c << 9) | (c >> 23);
83
            b += ((c & (d | a)) | (d & a)) + nt_buffer[13] + DefineConstants.SQRT_2; b = (b << 13) | (b >> 19);
84
85
            a += ((b & (c | d)) | (c & d)) + nt_buffer[2] + DefineConstants.SQRT_2; a = (a << 3) | (a >> 29);
86
            d += ((a & (b | c)) | (b & c)) + nt_buffer[6] + DefineConstants.SQRT_2; d = (d << 5) | (d >> 27);
87
            c += ((d & (a | b)) | (a & b)) + nt_buffer[10] + DefineConstants.SQRT_2; c = (c << 9) | (c >> 23);
88
            b += ((c & (d | a)) | (d & a)) + nt_buffer[14] + DefineConstants.SQRT_2; b = (b << 13) | (b >> 19);
89
90
            a += ((b & (c | d)) | (c & d)) + nt_buffer[3] + DefineConstants.SQRT_2; a = (a << 3) | (a >> 29);
91
            d += ((a & (b | c)) | (b & c)) + nt_buffer[7] + DefineConstants.SQRT_2; d = (d << 5) | (d >> 27);
92
            c += ((d & (a | b)) | (a & b)) + nt_buffer[11] + DefineConstants.SQRT_2; c = (c << 9) | (c >> 23);
93
            b += ((c & (d | a)) | (d & a)) + nt_buffer[15] + DefineConstants.SQRT_2; b = (b << 13) | (b >> 19);
94
            
95
            /* Round 3 */
96
            a += (d ^ c ^ b) + nt_buffer[0] + DefineConstants.SQRT_3; a = (a << 3) | (a >> 29);
97
            d += (c ^ b ^ a) + nt_buffer[8] + DefineConstants.SQRT_3; d = (d << 9) | (d >> 23);
98
            c += (b ^ a ^ d) + nt_buffer[4] + DefineConstants.SQRT_3; c = (c << 11) | (c >> 21);
99
            b += (a ^ d ^ c) + nt_buffer[12] + DefineConstants.SQRT_3; b = (b << 15) | (b >> 17);
100
101
            a += (d ^ c ^ b) + nt_buffer[2] + DefineConstants.SQRT_3; a = (a << 3) | (a >> 29);
102
            d += (c ^ b ^ a) + nt_buffer[10] + DefineConstants.SQRT_3; d = (d << 9) | (d >> 23);
103
            c += (b ^ a ^ d) + nt_buffer[6] + DefineConstants.SQRT_3; c = (c << 11) | (c >> 21);
104
            b += (a ^ d ^ c) + nt_buffer[14] + DefineConstants.SQRT_3; b = (b << 15) | (b >> 17);
105
106
            a += (d ^ c ^ b) + nt_buffer[1] + DefineConstants.SQRT_3; a = (a << 3) | (a >> 29);
107
            d += (c ^ b ^ a) + nt_buffer[9] + DefineConstants.SQRT_3; d = (d << 9) | (d >> 23);
108
            c += (b ^ a ^ d) + nt_buffer[5] + DefineConstants.SQRT_3; c = (c << 11) | (c >> 21);
109
            b += (a ^ d ^ c) + nt_buffer[13] + DefineConstants.SQRT_3; b = (b << 15) | (b >> 17);
110
111
            a += (d ^ c ^ b) + nt_buffer[3] + DefineConstants.SQRT_3; a = (a << 3) | (a >> 29);
112
            d += (c ^ b ^ a) + nt_buffer[11] + DefineConstants.SQRT_3; d = (d << 9) | (d >> 23);
113
            c += (b ^ a ^ d) + nt_buffer[7] + DefineConstants.SQRT_3; c = (c << 11) | (c >> 21);
114
            b += (a ^ d ^ c) + nt_buffer[15] + DefineConstants.SQRT_3; b = (b << 15) | (b >> 17);
115
116
            output[0] = a + DefineConstants.INIT_A;
117
            output[1] = b + Convert.ToUInt32(DefineConstants.INIT_B);
118
            output[2] = c + Convert.ToUInt32(DefineConstants.INIT_C);
119
            output[3] = d + DefineConstants.INIT_D;
120
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
121
            // Convert the hash to hex (for being readable)
122
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
123
            for (i = 0; i < 4; i++)
124
            {
125
                int j = 0;
126
                uint n = output[i];
127
                //iterate the bytes of the integer    
128
                for (; j < 4; j++)
129
                {
130
                    uint convert = n % 256;
131
                    hex_format[i * 8 + j * 2 + 1] = itoa16[Convert.ToInt16(convert % 16)];
132
                    convert = convert / 16;
133
                    hex_format[i * 8 + j * 2 + 0] = itoa16[Convert.ToInt16(convert % 16)];
134
                    n = n / 256;
135
                }
136
            }
137
            //null terminate the string
138
            hex_format[33] = "0".ToCharArray()[0];
139
            foreach (char k in hex_format)
140
            {
141
                result += k.ToString();
142
            }
143
        }
144
145
146
        internal static partial class DefineConstants
147
        {
148
          public const int INIT_A = 0x67452301;
149
          public const long INIT_B = 0xefcdab89;
150
          public const long INIT_C = 0x98badcfe;
151
          public const int INIT_D = 0x10325476;
152
          public const int SQRT_2 = 0x5a827999;
153
          public const int SQRT_3 = 0x6ed9eba1;
154
        }
155
}
156
}

von Markus (Gast)


Lesenswert?

Hi Sebastian,

das ist doch schon annähernd richtig. Ich habe mal Deine Version noch 
korrigiert und etwas optimiert. Ich habe dabei Deinen Ausgangscode, wo 
verbesserungsfähig, auskommentiert und meine Version reingeschrieben. 
Wenn Du dann noch die "überflüssigen" Kommentare entfernst, wird das 
ganze noch deutlich übersichtlicher.

Grüße
Markus

1
//#define INIT_A
2
//#define INIT_B
3
//#define INIT_C
4
//#define INIT_D
5
//#define SQRT_2
6
//#define SQRT_3
7
using System;
8
using System.Text;
9
10
namespace NTLM
11
{
12
    internal class _NTLM
13
    {
14
        private const uint INIT_A = 0x67452301;
15
        private const uint INIT_B = 0xefcdab89;
16
        private const uint INIT_C = 0x98badcfe;
17
        private const uint INIT_D = 0x10325476;
18
        private const uint SQRT_2 = 0x5a827999;
19
        private const uint SQRT_3 = 0x6ed9eba1;
20
21
        //private static uint[] nt_buffer = new uint[16];
22
        //private static uint[] output = new uint[4];
23
        //private static char[] hex_format = new char[34];
24
        //public static string result = "";
25
        //private static string itoa16 = "0123456789abcdef";
26
        //*************************************************************** 
27
28
        //public static void NTLM(string key)
29
        public static string Crypt(string key)
30
        {
31
            //int i = 0;
32
            //int length = key.Length;
33
34
            //memset(nt_buffer, 0, 16 * 4);
35
            //for (int z = 0; z < nt_buffer.Length; z++)
36
            //{
37
            //    nt_buffer[z] = 16*4;
38
            //}
39
40
            // The length of key need to be <= 27 (bytes)
41
            // oder 13 char in C#
42
            if (key.Length > 13)
43
                key = key.Substring(0, 13);
44
45
            //for (; i < length/2; i++)
46
            //{
47
            //    nt_buffer[i] = Convert.ToUInt32(key[2*i] | (key[2*i + 1] << 16));
48
            //}
49
            //if (length%2 == 1)
50
            //{
51
            //    nt_buffer[i] = Convert.ToUInt32(key[length - 1] | 0x800000);
52
            //}
53
            //else
54
            //{
55
            //    nt_buffer[i] = 0x80;
56
            //}
57
            ////put the length
58
            //nt_buffer[14] = Convert.ToUInt32(length << 4);
59
60
            var nt_buffer = new uint[16];
61
62
            // strings in C# sind IMMER Unicode, d.h. 1 char sind immer 2 bytes!
63
            var i = 0;
64
            foreach (var item in key)
65
            {
66
                var bytes = BitConverter.GetBytes(item);
67
                nt_buffer[i] = (uint)(bytes[0] | (bytes[1] << 16));
68
                i++;
69
            }
70
            nt_buffer[i] = 0x80;
71
            nt_buffer[14] = Convert.ToUInt32(key.Length << 4);
72
            // evtl. ist die folgende Zeile richtig und die vorhergehende falsch??
73
            //nt_buffer[i+1] = Convert.ToUInt32(key.Length << 4);
74
75
            uint a = INIT_A;
76
            uint b = INIT_B;
77
            uint c = INIT_C;
78
            uint d = INIT_D;
79
80
            /* Round 1 */
81
            a += (d ^ (b & (c ^ d))) + nt_buffer[0]; a = (a << 3) | (a >> 29);
82
            d += (c ^ (a & (b ^ c))) + nt_buffer[1]; d = (d << 7) | (d >> 25);
83
            c += (b ^ (d & (a ^ b))) + nt_buffer[2]; c = (c << 11) | (c >> 21);
84
            b += (a ^ (c & (d ^ a))) + nt_buffer[3]; b = (b << 19) | (b >> 13);
85
86
            a += (d ^ (b & (c ^ d))) + nt_buffer[4]; a = (a << 3) | (a >> 29);
87
            d += (c ^ (a & (b ^ c))) + nt_buffer[5]; d = (d << 7) | (d >> 25);
88
            c += (b ^ (d & (a ^ b))) + nt_buffer[6]; c = (c << 11) | (c >> 21);
89
            b += (a ^ (c & (d ^ a))) + nt_buffer[7]; b = (b << 19) | (b >> 13);
90
91
            a += (d ^ (b & (c ^ d))) + nt_buffer[8]; a = (a << 3) | (a >> 29);
92
            d += (c ^ (a & (b ^ c))) + nt_buffer[9]; d = (d << 7) | (d >> 25);
93
            c += (b ^ (d & (a ^ b))) + nt_buffer[10]; c = (c << 11) | (c >> 21);
94
            b += (a ^ (c & (d ^ a))) + nt_buffer[11]; b = (b << 19) | (b >> 13);
95
96
            a += (d ^ (b & (c ^ d))) + nt_buffer[12]; a = (a << 3) | (a >> 29);
97
            d += (c ^ (a & (b ^ c))) + nt_buffer[13]; d = (d << 7) | (d >> 25);
98
            c += (b ^ (d & (a ^ b))) + nt_buffer[14]; c = (c << 11) | (c >> 21);
99
            b += (a ^ (c & (d ^ a))) + nt_buffer[15]; b = (b << 19) | (b >> 13);
100
101
            /* Round 2 */
102
            a += ((b & (c | d)) | (c & d)) + nt_buffer[0] + SQRT_2; a = (a << 3) | (a >> 29);
103
            d += ((a & (b | c)) | (b & c)) + nt_buffer[4] + SQRT_2; d = (d << 5) | (d >> 27);
104
            c += ((d & (a | b)) | (a & b)) + nt_buffer[8] + SQRT_2; c = (c << 9) | (c >> 23);
105
            b += ((c & (d | a)) | (d & a)) + nt_buffer[12] + SQRT_2; b = (b << 13) | (b >> 19);
106
107
            a += ((b & (c | d)) | (c & d)) + nt_buffer[1] + SQRT_2; a = (a << 3) | (a >> 29);
108
            d += ((a & (b | c)) | (b & c)) + nt_buffer[5] + SQRT_2; d = (d << 5) | (d >> 27);
109
            c += ((d & (a | b)) | (a & b)) + nt_buffer[9] + SQRT_2; c = (c << 9) | (c >> 23);
110
            b += ((c & (d | a)) | (d & a)) + nt_buffer[13] + SQRT_2; b = (b << 13) | (b >> 19);
111
112
            a += ((b & (c | d)) | (c & d)) + nt_buffer[2] + SQRT_2; a = (a << 3) | (a >> 29);
113
            d += ((a & (b | c)) | (b & c)) + nt_buffer[6] + SQRT_2; d = (d << 5) | (d >> 27);
114
            c += ((d & (a | b)) | (a & b)) + nt_buffer[10] + SQRT_2; c = (c << 9) | (c >> 23);
115
            b += ((c & (d | a)) | (d & a)) + nt_buffer[14] + SQRT_2; b = (b << 13) | (b >> 19);
116
117
            a += ((b & (c | d)) | (c & d)) + nt_buffer[3] + SQRT_2; a = (a << 3) | (a >> 29);
118
            d += ((a & (b | c)) | (b & c)) + nt_buffer[7] + SQRT_2; d = (d << 5) | (d >> 27);
119
            c += ((d & (a | b)) | (a & b)) + nt_buffer[11] + SQRT_2; c = (c << 9) | (c >> 23);
120
            b += ((c & (d | a)) | (d & a)) + nt_buffer[15] + SQRT_2; b = (b << 13) | (b >> 19);
121
122
            /* Round 3 */
123
            a += (d ^ c ^ b) + nt_buffer[0] + SQRT_3; a = (a << 3) | (a >> 29);
124
            d += (c ^ b ^ a) + nt_buffer[8] + SQRT_3; d = (d << 9) | (d >> 23);
125
            c += (b ^ a ^ d) + nt_buffer[4] + SQRT_3; c = (c << 11) | (c >> 21);
126
            b += (a ^ d ^ c) + nt_buffer[12] + SQRT_3; b = (b << 15) | (b >> 17);
127
128
            a += (d ^ c ^ b) + nt_buffer[2] + SQRT_3; a = (a << 3) | (a >> 29);
129
            d += (c ^ b ^ a) + nt_buffer[10] + SQRT_3; d = (d << 9) | (d >> 23);
130
            c += (b ^ a ^ d) + nt_buffer[6] + SQRT_3; c = (c << 11) | (c >> 21);
131
            b += (a ^ d ^ c) + nt_buffer[14] + SQRT_3; b = (b << 15) | (b >> 17);
132
133
            a += (d ^ c ^ b) + nt_buffer[1] + SQRT_3; a = (a << 3) | (a >> 29);
134
            d += (c ^ b ^ a) + nt_buffer[9] + SQRT_3; d = (d << 9) | (d >> 23);
135
            c += (b ^ a ^ d) + nt_buffer[5] + SQRT_3; c = (c << 11) | (c >> 21);
136
            b += (a ^ d ^ c) + nt_buffer[13] + SQRT_3; b = (b << 15) | (b >> 17);
137
138
            a += (d ^ c ^ b) + nt_buffer[3] + SQRT_3; a = (a << 3) | (a >> 29);
139
            d += (c ^ b ^ a) + nt_buffer[11] + SQRT_3; d = (d << 9) | (d >> 23);
140
            c += (b ^ a ^ d) + nt_buffer[7] + SQRT_3; c = (c << 11) | (c >> 21);
141
            b += (a ^ d ^ c) + nt_buffer[15] + SQRT_3; b = (b << 15) | (b >> 17);
142
143
            var output = new uint[4];
144
            output[0] = a + INIT_A;
145
            output[1] = b + INIT_B;
146
            output[2] = c + INIT_C;
147
            output[3] = d + INIT_D;
148
149
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
150
            // Convert the hash to hex (for being readable)
151
            //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152
            //for (i = 0; i < 4; i++)
153
            //{
154
            //    int j = 0;
155
            //    uint n = output[i];
156
            //    //iterate the bytes of the integer    
157
            //    for (; j < 4; j++)
158
            //    {
159
            //        uint convert = n%256;
160
            //        hex_format[i*8 + j*2 + 1] = itoa16[Convert.ToInt16(convert%16)];
161
            //        convert = convert/16;
162
            //        hex_format[i*8 + j*2 + 0] = itoa16[Convert.ToInt16(convert%16)];
163
            //        n = n/256;
164
            //    }
165
            //}
166
            ////null terminate the string
167
            //hex_format[33] = "0".ToCharArray()[0];
168
            //foreach (char k in hex_format)
169
            //{
170
            //    result += k.ToString();
171
            //}
172
            var buffer = new StringBuilder();
173
            foreach (var o in output)
174
            {
175
                buffer.Append(o.ToString("X8"));
176
            }
177
            return buffer.ToString();
178
        }
179
180
        //internal static partial class DefineConstants
181
        //{
182
        //    public const int INIT_A = 0x67452301;
183
        //    public const long INIT_B = 0xefcdab89;
184
        //    public const long INIT_C = 0x98badcfe;
185
        //    public const int INIT_D = 0x10325476;
186
        //    public const int SQRT_2 = 0x5a827999;
187
        //    public const int SQRT_3 = 0x6ed9eba1;
188
        //}
189
    }
190
}

von Sebastian N. (sebastian_neusch)


Lesenswert?

Hey konnte wegen technischer Probleme länger nicht mehr auf die Seite 
aber hey vielen vielen vielen dank für die Übersetzung ihr seit genial.
Gibt es bei diesem Source code noch 
geschwindigkeitsoptimierungsmöglichkeiten

von Markus (Gast)


Lesenswert?

Eine Kleinigkeit könnte noch optimiert werden. Anstelle von
1
    var output = new uint[4];
2
    output[0] = a + INIT_A;
3
    output[1] = b + INIT_B;
4
    output[2] = c + INIT_C;
5
    output[3] = d + INIT_D;
6
7
    var buffer = new StringBuilder();
8
    foreach (var o in output)
9
    {
10
        buffer.Append(o.ToString("X8"));
11
    }
12
    return buffer.ToString();

könntest Du folgendes schreiben:
1
    var buffer = new StringBuilder();
2
    buffer.Append((a+INIT_A).ToString("X8"));
3
    buffer.Append((b+INIT_B).ToString("X8"));
4
    buffer.Append((c+INIT_C).ToString("X8"));
5
    buffer.Append((d+INIT_D).ToString("X8"));
6
    return buffer.ToString();

Dadurch fällt der Overhead für das Anlegen und Füllen des output Arrays 
und für die foreach Schleife weg.

Grüße
Markus

von Sebastian N. (sebastian_neusch)


Lesenswert?

Hey Leute vielen Dank so will ich das in nem Forum sehen vielen Dank

von Sebastian N. (sebastian_neusch)


Lesenswert?

Äh Jungs des kann irg wie net stimmen
da kommt was anderes raus wie wenn ich smit nem richtigen vergleich

von Mike (Gast)


Lesenswert?

Sebastian N. schrieb:
> Äh Jungs des kann irg wie net stimmen
> da kommt was anderes raus wie wenn ich smit nem richtigen vergleich

Liest du auch, was während deiner Abwesenheit vom Thread geschieben 
wurde?

Boris P. schrieb:
> Danach lässt du beide Programme mal mit dem gleichen Input und einem
> Debugger Schritt für Schritt nebeneinander laufen, und schaust dir die
> Zwischenergebnisse an. Wenn sich dein C# Programm dann anders verhalten
> sollte, findest du das so ganz schnell heraus.

von Markus (Gast)


Lesenswert?

Oder wenn schon nicht Debugger, dann zumindest Testausgaben im Bereich 
der Codestrellen, die sich in der C#-Variante vom Originalcode 
substantiell unterscheiden: Umwandlung des Input-Keys in ein uint-Array 
-> sind die Arrays gleich. Eine mögliche "Fehlerquelle" wäre es, dass 
die beiden Bytes vertauscht werden müssen, die 
BitConverter.GetBytes(item) liefert.

Dann wäre es möglich, dass beim Umwandeln in einen Hex-String der 
bequeme Weg über ToString("X8") durch eine Lösung mit 
BitConverter.GetBytes(...) und ToString("X2") ersetzt werden müsste, 
weil auch hier die Reihenfolge der Bytes im Output Strings falsch ist...

Ein bisschen Arbeit musst Du schon selbst erledigen... ;-)

Grüße
Markus

von Sebastian N. (sebastian_neusch)


Lesenswert?

Ok vielen Dank ich werde mal nen debugger laufen lassen und vergleichen, 
hab grad leider blos visual c# express und kein visual studio dass ich 
alle versionen hätet

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.