해시 값을 생성하는 Excel 함수가 있습니까?


26

문서 이름으로 키가 지정된 여러 데이터 목록으로 작업하고 있습니다. 문서 이름은 매우 설명 적이지만 (256 바이트까지는 많은 부동산)을 볼 필요가 있으면 상당히 번거롭고 필요한 경우 쉽게 재현 할 수있는 작은 키 필드를 만들 수 있기를 바랍니다. VLOOKUP다른 워크 시트 또는 통합 문서에서 작업을 수행합니다 .

나는 독특하고 재현 할 것 제목에서 해시를 생각하고 있어요 가장 적합 할 것이다 각 제목입니다. 사용 가능한 기능이 있습니까, 아니면 자체 알고리즘을 개발하려고합니까?

이 전략이나 다른 전략에 대한 생각이나 아이디어가 있습니까?

답변:


34

당신은 자신의 함수를 작성할 필요가 없습니다-다른 사람들은 이미 당신을 위해 그것을했습니다.
예를 들어이 스택 오버 플로우 응답 에서 5 개의 VBA 해시 함수를 수집하고 비교했습니다.

개인적으로이 VBA 기능을 사용합니다

  • =BASE64SHA1(A1)매크로를 VBA 모듈에 복사 한 후 Excel에서 호출
  • "Microsoft MSXML"라이브러리를 사용하므로 .NET이 필요합니다 (늦게 바인딩 됨).

Public Function BASE64SHA1(ByVal sTextToHash As String)

    Dim asc As Object
    Dim enc As Object
    Dim TextToHash() As Byte
    Dim SharedSecretKey() As Byte
    Dim bytes() As Byte
    Const cutoff As Integer = 5

    Set asc = CreateObject("System.Text.UTF8Encoding")
    Set enc = CreateObject("System.Security.Cryptography.HMACSHA1")

    TextToHash = asc.GetBytes_4(sTextToHash)
    SharedSecretKey = asc.GetBytes_4(sTextToHash)
    enc.Key = SharedSecretKey

    bytes = enc.ComputeHash_2((TextToHash))
    BASE64SHA1 = EncodeBase64(bytes)
    BASE64SHA1 = Left(BASE64SHA1, cutoff)

    Set asc = Nothing
    Set enc = Nothing

End Function

Private Function EncodeBase64(ByRef arrData() As Byte) As String

    Dim objXML As Object
    Dim objNode As Object

    Set objXML = CreateObject("MSXML2.DOMDocument")
    Set objNode = objXML.createElement("b64")

    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    EncodeBase64 = objNode.text

    Set objNode = Nothing
    Set objXML = Nothing

End Function

해시 길이 사용자 정의

  • 해시는 처음에 28 자 길이의 유니 코드 문자열입니다 (대소 문자 구분 + 특수 문자)
  • 이 줄을 사용하여 해시 길이를 사용자 정의하십시오. Const cutoff As Integer = 5
  • 4 자리 해시 = 6895 줄의 36 번 충돌 = 0.5 % 충돌 률
  • 6895 라인에서 5 자리 해시 = 0 충돌 = 0 % 충돌 속도

.NET을 필요로하지 않으며 외부 라이브러리를 사용하지 않는 해시 함수 ( 세 CRC16 함수 모두 )가 있습니다. 그러나 해시는 더 길고 더 많은 충돌을 일으 킵니다.

예제 통합 문서를 다운로드 하고 5 개의 해시 구현을 모두 사용할 수 있습니다. 보시다시피 첫 번째 시트에 대한 좋은 비교가 있습니다.


1
좋아 보인다. 그러나 Excel에서을 반환하지 못하도록 VBA 경험이 충분하지 않습니다 #NAME?. 코드보기> 코드를 잘라내어 새 창에 붙여 넣기-탐색기의 올바른 워크 시트 내에서> 매크로 사용 워크 시트로 저장> 닫고 Excel로 돌아갑니다 ... 어떻게 든 컴파일해야합니까?
dwwilson66

예 ... 명확하게하기 위해 ... 워크 시트 탭으로 이동했을 때 팝업 된 새 코드 창에 붙여 넣었습니다. 코드보기 ... 지금 샘플을 다운로드하지만 Excel에서 내 코드를 인식하지 못하는 이유를 이해하고 싶습니다.
dwwilson66

우후 ... 샘플 시트가 도움이되었습니다. 실현했습니다. 모듈 창이 아닌 코드를 붙여 넣은 OBJECT 창에 붙여 넣었습니다. 통합 문서에 해시가 나타납니다.
dwwilson66

1
이것은 훌륭한 도구입니다.
Jay Killeen

1
cutoff함수 매개 변수 목록으로 이동 하여 매개 변수화 및 선택 사항을 다른 기본값으로 설정 Public Function BASE64SHA1(ByVal sTextToHash As String, Optional ByVal cutoff As Integer = 8) 하고 함수 내부에서 선언을 제거 할 수 있습니다.
핵심

9

나는 충돌에 대해서는별로 신경 쓰지 않지만 가변 길이 문자열 필드를 기반으로 약한 행의 의사 난 수화기가 필요했습니다. 다음은 잘 작동하는 미친 솔루션입니다.

=MOD(MOD(MOD(MOD(MOD(IF(LEN(Z2)>=1,CODE(MID(Z2,1,1))+10,31),1009)*IF(LEN(Z2)>=3,CODE(MID(Z2,3,1))+10,41),1009)*IF(LEN(Z2)>=5,CODE(MID(Z2,5,1))+10,59),1009)*IF(LEN(Z2)>=7,CODE(MID(Z2,7,1))+10,26),1009)*IF(LEN(Z2)>=9,CODE(MID(Z2,9,1))+10,53),1009)

Z2해시하려는 문자열을 포함하는 셀은 어디에 있습니까 ?

"MOD"는 과학적 표기법으로 넘치지 않도록하기 위해 존재합니다. 1009소수입니다. X * 255 <가되도록 X를 사용할 수 있습니다 max_int_size. 10은 임의적이다; 아무것도 사용하십시오. "다른"값은 임의적입니다 (여기서 pi의 숫자!). 아무것도 사용하십시오. 문자 (1,3,5,7,9)의 위치는 임의적입니다. 아무것도 사용하십시오.


2
솔직히 이것은 가장 간단한 대답입니다. 대부분의 Excel 사용 사례에서 충돌이 문제가 될 것입니다.

3

상당히 작은 목록의 경우 기본 제공 Excel 함수를 사용하여 스크램블러 (가난한 사람의 해시 함수)를 만들 수 있습니다.

예 :

 =CODE(A2)*LEN(A2) + CODE(MID(A2,$A$1,$B$1))*LEN(MID(A2,$A$1,$B$1))

여기에서 A1과 B1은 임의의 시작 문자와 문자열 길이를가집니다.

약간의 검토와 점검 그리고 대부분의 경우 작업 가능한 고유 ID를 매우 빠르게 얻을 수 있습니다.

작동 방식 : 수식은 문자열의 첫 번째 문자와 중간 문자열에서 가져온 고정 문자를 사용하고 LEN ()을 '팬 기능'으로 사용하여 충돌 가능성을 줄입니다.

주의해야 할 점은 이는 하지 해시,하지만 당신은 신속하게 수행 뭔가를 얻을 필요가 있고, 어떤 충돌이 없는지 확인하기 위해 결과를 검사 할 수 있습니다 때, 그것은 아주 잘 작동합니다.

편집 : 문자열에 가변 길이 (예 : 전체 이름)가 있어야하지만 고정 너비 필드가있는 데이터베이스 레코드에서 가져온 경우 다음과 같이하십시오.

 =CODE(TRIM(C8))*LEN(TRIM(C8))
       +CODE(MID(TRIM(C8),$A$1,1))*LEN(MID(TRIM(C8),$A$1,$B$1))

길이는 의미있는 스크램블러입니다.


1
좋은 답변입니다! (: "가난한 사람의 해시 함수", "caveat", "작동 방식":)
natty에 대한 nutty

1
"충돌이 없는지 확인하기 위해 결과를 검사 하려면 " DATA> REMOVE DUPLICATES를 실행하여이를 시도 / 테스트하고있을 수 있습니다. [분명히 / 아마도, 중복을 권장한다면 중복이 남지 않을 때까지 위의 기능을 반복해서 다시 실행할 수 있습니다]
nutty about natty

2

매번 스크립트를 실행할 필요없이 충돌을 방지하면서 꽤 좋은 결과를 제공하는 이것을 사용하고 있습니다. 0-1 사이의 값이 필요했습니다.

=ABS(COS((CODE(MID(A2,ROUNDUP(LEN(A2)/9,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)/5,0),1))+100)/CODE(MID(A2,ROUNDUP(LEN(A2)/3,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)*8/9,0),1))+25)/CODE(MID(A2,ROUNDUP(LEN(A2)*6/9,0),1))*(CODE(MID(A2,ROUNDUP(LEN(A2)*4/9,0),1))-25))/LEN(A2)+CODE(A2)))

문자열 전체에서 문자를 선택하고 각 문자의 값을 가져 와서 값을 추가하여 (같은 장소에서 같은 문자가 동일한 결과를 제공하지 않도록) 각각 곱하거나 나누고 총계에 대해 COS 함수를 실행합니다.


1

당신은 이것을 시도 할 수 있습니다. 두 열에서 Pseudo #를 실행하십시오.

= + IF (AND (ISBLANK (D3), ISBLANK (E3)), "", CODE (TRIM (D3 & E3)) * LEN (TRIM (D3 & E3)) + CODE (MID (TRIM (D3 & E3), $ A $ 1 * LEN (D3 & E3), 1)) INT (LEN (TRIM (D3 & E3)) $ B $ 1))

A1 및 B1이 수동으로 입력 한 임의의 시드를 저장하는 경우 : 0


0

내 지식으로는 Excel에 해시 함수가 빌드되어 있지 않으므로 VBA에서 사용자 정의 함수로 빌드해야합니다.

그러나 귀하의 목적을 위해 해시를 사용하는 것이 필요하거나 실제로 유리하다고 생각하지 않습니다. VLOOKUP더 작은 해시에있을 것이므로 256 바이트에서도 잘 작동합니다. 물론, 그것은 조금 더 느릴 수 있습니다-비트는 너무 작아서 측정 할 수 없습니다. 그런 다음 해시 값을 추가하는 것이 더 많은 노력입니다.


그래 ... 알지만, 프리젠 테이션 관점에서 볼 때, title왼쪽 고정 된 창에서 256 바이트의 해시 15 바이트의 해시를 표시 하려고합니다 ...
dwwilson66
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.