코딩도장

해시의 충돌값 찾기

이 문제는 주어진 해시의 충돌(두 입력이 같은 출력을 가지는 경우)을 찾는 문제입니다. 해시함수는 python 언어로 작성되었습니다.

def numerize(string: str) -> list[int]:
 result = []
 for char in string:
 result.append(ord(char)-96)
 return result
def hash(num_string: list[int]) -> int:
 result = 0
 for i in range(len(num_string)):
 result += ((i+2) ** (num_string[i])) * 2
 result -= (i+2) ** (num_string[::-1][i])
 return (result) % 100000007
 print(hash(numerize(input())))

numerize 함수는 전처리 함수이고, hash 함수가 메인입니다. 이 코드는 임의의 문자열을 받으면 numerize와 hash를 차례로 지나며 0 이상 100000007 미만의 정수를 출력합니다.

문제: 주어진 해시함수의 충돌을 찾는 코드와, 그 코드의 실행 결과로 str1, str2, hash_num 꼴의 출력(str1과 2는 충돌이 발생하는 문자열, hash_num은 충돌되는 해시값) 5개 이상을 제출하시오. 당연히 많이 제출할수록 좋은 답이 되겠습니다.

hash

2023年07月23日 19:54

이준우

(追記) (追記ここまで)
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

1개의 풀이가 있습니다.

Python 3.12

numerize 함수에서 ord(char) - 96 연산을 하므로, 유니코드 값이 96 미만인 경우 hash 함수에서 음(-)의 지수 연산으로 인해 반환 값이 float이 될 수 있음(Type hint에서는 int로 명시). 따라서, 유니코드 값 96 이상의 출력가능한 문자열만 입력되는 것으로 가정

import itertools
import string
def numerize(string: str) -> list[int]:
 result = []
 for char in string:
 result.append(ord(char) - 96)
 return result
def hash(num_string: list[int]) -> int:
 result = 0
 for i in range(len(num_string)):
 result += ((i + 2) ** (num_string[i])) * 2
 result -= (i + 2) ** (num_string[::-1][i])
 return (result) % 100000007
def find_cases(assumelen=3):
 # 유니코드 96 이상의 출력 가능한 문자열에 대해 길이 3인 문자열 순열 생성
 pool = [
 c for c in string.printable if (c not in string.whitespace) and (ord(c) >= 96)
 ]
 teststrs = ("".join(c) for c in itertools.permutations(pool, assumelen))
 testrst: dict[int, list[str]] = {} # key: hash => value: list[문자열]
 for teststr in teststrs:
 hashval = hash(numerize(teststr))
 if hashval in testrst:
 testrst[hashval].append(teststr)
 else:
 testrst[hashval] = [teststr]
 # 충돌이 발생하는 문자열 선택
 rst = sorted((k, v) for k, v in testrst.items() if len(v) > 1)
 for k, v in rst:
 print(f"{", ".join(v)}, {k}")
if __name__ == "__main__":
 find_cases()
"""
bc`, de`, 20
bca, dea, 25
cd`, `ca, 34
adc, cea, 201
df`, `bd, 506
c`e, dga, 1969
bcf, def, 8147
bcg, deg, 32659
bch, deh, 130835
bci, dei, 523795
bcj, dej, 2096147
bck, dek, 8386579
pn`, ste, 9947047
bc}, de}, 14302797
bc|, de|, 19357996
bct, det, 22053065
bcy, dey, 22504863
bc~, de~, 30952878
bcl, del, 33550355
bcm, dem, 34209548
bcn, den, 36854512
bcr, der, 38681729
fpj, ~gd, 45138881
mnk, noh, 46077056
bco, deo, 47450752
bcs, des, 55251140
bcz, dez, 57128252
bcq, deq, 59604914
bc{, de{, 62730658
bcv, dev, 65431646
bcw, dew, 70115121
bcp, dep, 89868480
bcu, deu, 90309355
bcx, dex, 97237629
"""
댓글 작성은 로그인이 필요합니다.
(注記) 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

(注記) 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
풀이 작성은 로그인이 필요합니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.

hash x 1

언어별 풀이 현황
전 체 x 1
python x 1
코딩도장 © 2014 · 문의 [email protected]
피드백 · 개인정보취급방침 · RSS

AltStyle によって変換されたページ (->オリジナル) /