문서 이름으로 키가 지정된 여러 데이터 목록으로 작업하고 있습니다. 문서 이름은 매우 설명 적이지만 (256 바이트까지는 많은 부동산)을 볼 필요가 있으면 상당히 번거롭고 필요한 경우 쉽게 재현 할 수있는 작은 키 필드를 만들 수 있기를 바랍니다. VLOOKUP
다른 워크 시트 또는 통합 문서에서 작업을 수행합니다 .
나는 독특하고 재현 할 것 제목에서 해시를 생각하고 있어요 에 가장 적합 할 것이다 각 제목입니다. 사용 가능한 기능이 있습니까, 아니면 자체 알고리즘을 개발하려고합니까?
이 전략이나 다른 전략에 대한 생각이나 아이디어가 있습니까?
답변
당신은 자신의 함수를 작성할 필요가 없습니다-다른 사람들은 이미 당신을 위해 그것을했습니다.
예를 들어이 스택 오버 플로우 응답 에서 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 개의 해시 구현을 모두 사용할 수 있습니다. 보시다시피 첫 번째 시트에 대한 좋은 비교가 있습니다.
답변
나는 충돌에 대해서는별로 신경 쓰지 않지만 가변 길이 문자열 필드를 기반으로 약한 행의 의사 난 수화기가 필요했습니다. 다음은 잘 작동하는 미친 솔루션입니다.
=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)의 위치는 임의적입니다. 아무것도 사용하십시오.
답변
상당히 작은 목록의 경우 기본 제공 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))
길이는 의미있는 스크램블러입니다.
답변
매번 스크립트를 실행할 필요없이 충돌을 방지하면서 꽤 좋은 결과를 제공하는 이것을 사용하고 있습니다. 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 함수를 실행합니다.
답변
당신은 이것을 시도 할 수 있습니다. 두 열에서 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
답변
내 지식으로는 Excel에 해시 함수가 빌드되어 있지 않으므로 VBA에서 사용자 정의 함수로 빌드해야합니다.
그러나 귀하의 목적을 위해 해시를 사용하는 것이 필요하거나 실제로 유리하다고 생각하지 않습니다. VLOOKUP
더 작은 해시에있을 것이므로 256 바이트에서도 잘 작동합니다. 물론, 그것은 조금 더 느릴 수 있습니다-비트는 너무 작아서 측정 할 수 없습니다. 그런 다음 해시 값을 추가하는 것이 더 많은 노력입니다.