2010-08-18 2 views
2

javascript와 C# 모두에서 GUID에 대해 동일한 균일하게 분포 된 숫자 해시를 생성 할 수 있어야하는 곳에 문제가 있습니다. C#에서 리버스 엔지니어링하지 않고도 JS에서 동작을 재현 할 수 없기 때문에 C#에서 Guid.GetHashCode()을 사용하지 못하게 될 것입니다.C#과 javascript의 guid에 대한 동일한 해시

빠른 JS의 guids/strings에서 해시를 생성하는 방법이 있습니까? 문자열의 모든 숫자가 .NET에서 생성 된 GUID에 균일하게 분포되어 있습니까? 내가 후행 문자를 캐스팅/int로 변환해야합니까?

답변

5

바이트는 분명히 균등하게 분배되지 않습니다.

내가 함께 .NET GUID를 샘플링하고 분배 플롯하는 몇 가지 코드를 넣어 모든 테스트 코드의

먼저,이 100 만 GUID를 생성하고 바이트 배열의 각 바이트에 대해 서로 다른 값의 수를 계산 . 그것은 모든 것을 Scilab에 그려진 매트릭스로 출력합니다. 여기

int[,] counter = new int[16, 256]; 
for (int i = 0; i < 1000000; i++) 
{ 
    var g = Guid.NewGuid(); 
    var bytes = g.ToByteArray(); 
    for (int idx = 0; idx < 16; idx++) 
    { 
     counter[idx, bytes[idx]]++; 
    } 
} 
StringBuilder sb = new StringBuilder(); 
sb.AppendLine("x = ["); 
for (int idx = 0; idx < 16; idx++) 
{ 
    for (int b = 0; b < 256; b++) 
    { 
     sb.Append(counter[idx, b]); 
     if (idx != 255) 
     { 
      sb.Append(" "); 
     } 
    } 
    if (idx != 15) 
    { 
     sb.AppendLine(";"); 
    } 
} 
sb.AppendLine("]"); 

File.WriteAllText("plot.sce", sb.ToString()); 

이 그래프 바이트 배열의 각각의 위치에 대한 각각의 고유 값의 개수를 플롯 분포이다 :

바이트 배열의 위치 0-6에 대한 값 분포 : The value distribution for the positions 0-6 in the byte array
바이트 배열의 위치 (7)에 대한 값 분포 :
The value distribution for the position 7 in the byte array
바이트 배열에서의 위치 (8)에 대한 값 분포 :
,210
값 바이트 배열의 위치 9-15에 대한 분포 : 바이트 위치에 대한 The value distribution for the positions 9-15 in the byte array

0-6 및 9-15 값의 분포에도 것으로 보이지만, 바이트 위치 (7) 및 (8)에 대한 배포가 상당히 제한적입니다. GUID를 들면

위치 (7) 79 (0x4F) 내지 64 (× 40)의 값을 취할 수

{1369ea05-b9f9-408b-ac7c-7ebd0f35d562} 
         1 1 1 1 1 1 
3 2 1 0 5 4 7 6 8 9 0 1 2 3 4 5 

(아래 바이트 위치의 시작과는 이상한 순서를 참고).
위치 8은 128 (0x80)에서 191 (0xBF)까지의 값을 취할 수 있습니다.
나머지 바이트는 고르게 분포됩니다.

참고 : 테스트는 .NET 기반의 32 비트 Windows 7 시스템에서 실행되었습니다.

학습 : 물건을 시험하지 마십시오.

Answer :로드 균형 조정을 계산하는 데 .NET Guids를 사용하려면 위의 Guid에서 7 및 8로 표시된 위치를 제외한 다른 부분을 사용할 수 있습니다.

질문 : 배포본이 균등하게 배포되지 않는 이유는 누구입니까?

+0

와우, 알빈. 당신은 그것을 얻었습니다! 고맙습니다. BTW :이 답변에 대한 의견은 비트가 pos 7 & 8에서 균일하지 않은 이유에 대한 단서를 제공합니다. http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in- javascript/105074 # 105074 아마도 비트 중 일부는 GUID의 생성 방법/출처에 대한 세부 정보를 제공합니까? –

+0

아, 일부 알고리즘 정보에 대한 버전 정보 및 마커. –

2

서버 측에서 해시 값을 생성하는 웹 서비스를 만들 수 있습니다. 원하는 언어를 사용할 수 있습니다. 클라이언트 쪽에서 간단한 웹 서비스 호출이 트릭을 수행합니다.

+1

나는 빠른 속도를 보였습니다. 서버로의 왕복 또는 서버 컴퓨터 간의 왕래를 피할 필요가있었습니다. 그것은 하드웨어를 필요로하지 않는로드 밸런싱을 허용하고, 기다리지 않고도 Ajax 앱이 정상적으로 페일 오버 할 수있게 해줍니다. –

+0

guid 해시 계산의 목적은 무엇입니까? 로드 균형 조정에 사용 하시겠습니까? –

+0

UI에서 들어오는 요청에 대해 캐시 데이터를 전달할 수 있도록 IIS 서버의 특정 하위 집합을 식별 할 수 있어야합니다 (서버 쪽 또는 클라이언트 쪽의 모든 위치에서). –

1

리플렉터는 .NET Guid.GetHashCode()이

public override int GetHashCode() 
{ 
    return ((this._a^((this._b << 0x10) | ((ushort) this._c)))^((this._f << 0x18) | this._k)); 
} 

_a, _B, _c 같이 구현되고 _f는 [16] 배열 바이트를 취하는 생성자에 정의 말한다

public Guid(byte[] b) 
{ 
    if (b == null) 
    { 
     throw new ArgumentNullException("b"); 
    } 
    if (b.Length != 0x10) 
    { 
     throw new ArgumentException(Environment.GetResourceString("Arg_GuidArrayCtor", new object[] { "16" })); 
    } 
    this._a = (((b[3] << 0x18) | (b[2] << 0x10)) | (b[1] << 8)) | b[0]; 
    this._b = (short) ((b[5] << 8) | b[4]); 
    this._c = (short) ((b[7] << 8) | b[6]); 
    this._d = b[8]; 
    this._e = b[9]; 
    this._f = b[10]; 
    this._g = b[11]; 
    this._h = b[12]; 
    this._i = b[13]; 
    this._j = b[14]; 
    this._k = b[15]; 
} 
+0

JS에서 GUID에 대한 문자열 기반이 아닌 표현이 있습니까? 문자열 변환 (그 내가받은 것) 바이트 배열로, 그리고 문자열을 좋은 해시 만들 수있는 직접적인 방법이 있다면 int 생성하기 위해 GUID에 낭비가 될 것이라고 생각합니다. 대표. –

+0

로드 균형 조정을위한 인덱스를 만들려면이 기능이 과장된 것 같습니다. 바이트로의 변환은 문자 2를 2로 그룹화하고 16 진수 값으로 구문 분석하여 간단히 수행됩니다. 일부 바이트가 다른 바이트보다 더 많이 보이는 것처럼 배포판에서 일부 테스트를 수행했지만 차이점이 무엇인지에 대한 자세한 내용을 살펴야 만 관련 정보를 게시 할 수 있습니다. –

관련 문제