1
1
using System ;
2
2
using System . Collections ;
3
3
using System . Collections . Generic ;
4
- using System . Security . Cryptography ;
5
4
using System . Text ;
6
5
using NHibernate . Engine ;
7
6
using NHibernate . Util ;
@@ -74,96 +73,13 @@ public static string GenerateName(
74
73
// Hash the generated name for avoiding collisions with user choosen names.
75
74
// This is not 100% reliable, as hashing may still have a chance of generating
76
75
// collisions.
77
- var name = prefix + HashName ( sb . ToString ( ) ) ;
78
-
79
- // Hibernate uses an algorithm yielding names shorter than 30 characters. But we cannot
80
- // use it (see HashName). And also we have DB limited to even less (Informix)...
81
- if ( name . Length > 30 )
82
- {
83
- // This, of course, increases the collision risk.
84
- name = name . Substring ( 0 , 30 ) ;
85
- }
76
+ // Hibernate uses MD5 here, which .Net standrad implementation is rejected by
77
+ // FIPS enabled machine. Better use a non-cryptographic hash.
78
+ var name = prefix + Hasher . HashToString ( sb . ToString ( ) ) ;
86
79
87
80
return name ;
88
81
}
89
82
90
- #region Name generation support methods
91
-
92
- /// <summary>
93
- /// Hash a constraint name. Convert the hash digest to base 32
94
- /// (full alphanumeric) for shortening the hash string representation
95
- /// while keeping it suitable for db names.
96
- /// </summary>
97
- /// <param name="name">The name to be hashed.</param>
98
- /// <returns>The hased name.</returns>
99
- private static string HashName ( string name )
100
- {
101
- // Hibernate uses MD5, but with .Net this would throw on FIPS enabled machine.
102
- // As a consequence generated names will be quite longer.
103
- using ( var hasher = SHA256 . Create ( ) )
104
- {
105
- var hash = hasher . ComputeHash ( Encoding . UTF8 . GetBytes ( name ) ) ;
106
- // Converting to base 32 for shortening the name.
107
- // Hibernate uses base 35, but we do not have a native implementation
108
- // in .Net, and base 32 is easier to implement.
109
- return ToBase32String ( hash ) ;
110
- }
111
- }
112
-
113
- // Adapted from https://stackoverflow.com/a/7135008/1178314
114
- // Changed for not padding with "="
115
- private static string ToBase32String ( byte [ ] input )
116
- {
117
- if ( input == null || input . Length == 0 )
118
- {
119
- throw new ArgumentNullException ( nameof ( input ) ) ;
120
- }
121
-
122
- var charCount = ( int ) Math . Ceiling ( input . Length / 5d ) * 8 ;
123
- var result = new StringBuilder ( charCount ) ;
124
-
125
- byte nextChar = 0 , bitsRemaining = 5 ;
126
-
127
- foreach ( var b in input )
128
- {
129
- nextChar = ( byte ) ( nextChar | ( b >> ( 8 - bitsRemaining ) ) ) ;
130
- result . Append ( ValueToChar ( nextChar ) ) ;
131
-
132
- if ( bitsRemaining < 4 )
133
- {
134
- nextChar = ( byte ) ( ( b >> ( 3 - bitsRemaining ) ) & 31 ) ;
135
- result . Append ( ValueToChar ( nextChar ) ) ;
136
- bitsRemaining += 5 ;
137
- }
138
-
139
- bitsRemaining -= 3 ;
140
- nextChar = ( byte ) ( ( b << bitsRemaining ) & 31 ) ;
141
- }
142
-
143
- // If we didn't end with a full char
144
- if ( result . Length != charCount )
145
- {
146
- result . Append ( ValueToChar ( nextChar ) ) ;
147
- }
148
-
149
- return result . ToString ( ) ;
150
- }
151
-
152
- private static char ValueToChar ( byte b )
153
- {
154
- if ( b < 26 )
155
- {
156
- return ( char ) ( b + 65 ) ;
157
- }
158
-
159
- if ( b < 32 )
160
- {
161
- return ( char ) ( b + 24 ) ;
162
- }
163
-
164
- throw new ArgumentException ( "Byte is not a value Base32 value." , "b" ) ;
165
- }
166
-
167
83
private class ColumnComparator : IComparer < Column >
168
84
{
169
85
public static readonly ColumnComparator Instance = new ColumnComparator ( ) ;
@@ -173,8 +89,6 @@ public int Compare(Column col1, Column col2) {
173
89
}
174
90
}
175
91
176
- #endregion
177
-
178
92
/// <summary>
179
93
/// Adds the <see cref="Column"/> to the <see cref="ICollection"/> of
180
94
/// Columns that are part of the constraint.
0 commit comments