암호화 해시 골프


34

이 콘테스트는 끝났습니다.

도전 과제 의 특성으로 인해 관련 강도 도전에 대한 관심이 줄어들면 경찰 도전이 훨씬 쉬워집니다. 따라서 여전히 해시 함수를 게시 할 수 있지만 답변이 수락되지 않거나 리더 보드의 일부를 구성하지는 않습니다.

이 과제는 충돌에 강한 해시 함수 의 최단 구현을 검색 하는 것입니다 . 즉, 동일한 해시로 두 개의 다른 메시지를 찾을 수 없어야합니다.

경찰은 코드 크기와 충돌 내성 간의 최상의 절충안을 찾는 해시 함수를 발명하고 구현하려고합니다. 너무 많은 바이트를 사용하면 다른 경찰이 당신을 능가합니다!

강도로서, 경찰은 자신의 기능을 해독하여 부적합하다는 것을 증명함으로써 경찰의 ​​시도를 망가 뜨리려고합니다. 그러면 알고리즘을 강화하기 위해 더 많은 바이트를 사용하게됩니다!

경찰 도전

태스크

선택한 암호화 해시 함수 H : I-> O 를 구현하십시오. 여기서 I 는 2 2 30 미만 의 모든 음이 아닌 정수 세트 이고 O 는 2 128 미만의 모든 음이 아닌 정수 세트입니다 .

단일 정수, 정수 또는 정수 배열의 문자열 표현 또는 STDIN에서 읽고 기본 10 또는 16에서 STDOUT으로 인쇄하는 전체 프로그램을 받아들이고 리턴하는 실제 함수로 H 를 구현할 수 있습니다 .

채점

  • H 아래에 정의 된 강도 도전 에 저항 해야 합니다.

    강도가 게시 후 처음 168 시간 내에 제출을 물리 치면 금이 간 것으로 간주됩니다 .

  • H 의 구현은 가능한 한 짧아야합니다. 가장 짧은 무단 제출은 경찰 도전의 승자가 될 것입니다.

추가 규칙

  • H 를 함수로 구현하는 경우 위에서 설명한대로 동작하는 프로그램 내에서 함수를 실행할 래퍼를 제공하십시오.

  • 프로그램 또는 래퍼 (예 : 입력 및 해당 출력)에 대해 적어도 세 개의 테스트 벡터를 제공하십시오.

  • H 는 직접 구현하는 한 새로운 디자인 (선호) 또는 잘 알려진 알고리즘 일 수 있습니다. 내장 된 해시 함수, 압축 함수, 암호, PRNG 등을 사용하는 것은 금지되어 있습니다.

    해싱 함수 (예 : 기본 변환) 를 구현 하는 데 일반적으로 사용되는 모든 내장 게임은 공정한 게임입니다.

  • 프로그램 또는 함수의 출력은 결정적이어야합니다.

  • x86 또는 x64 플랫폼에서 또는 웹 브라우저 내에서 실행할 수있는 비어있는 컴파일러 / 인터프리터가 있어야합니다.

  • 귀하의 프로그램 또는 기능은 합리적으로 효율적 이어야하며 1 초 이내에 2 2 19 미만의 I 메시지를 해시해야합니다 .

    가장자리의 경우 내 컴퓨터 (Intel Core i7-3770, 16GiB RAM)에서 소요되는 (벽) 시간이 결정적입니다.

  • 이 과제의 특성상 출력 변경 여부에 관계없이 어떤 방식 으로든 답변 코드를 변경하는 것은 금지되어 있습니다.

    제출물에 금이 간 경우 (또는 그렇지 않은 경우에도) 추가 답변을 게시 할 수 있습니다.

    답변이 유효하지 않은 경우 (예 : I / O 사양을 준수하지 않는 경우) 삭제하십시오.

예

파이썬 2.7, 22 바이트

def H(M):
 return M%17

싸개

print H(int(input()))

강도 도전

태스크

'는 다음 사항을 게시하여 제출 경찰 어떠한 균열 스레드 강도' 개의 메시지 : M 및 N을 의 I 되도록 H (M) = H (N) 및 M ≠ N .

채점

  • 각 경찰 제출물을 크래킹하면 1 ​​포인트가됩니다. 가장 많은 점수를 얻은 강도가 승리합니다.

    동점 인 경우, 가장 긴 제출을 금한 묶인 강도가 승리합니다.

추가 규칙

  • 모든 경찰 제출은 한 번만 해킹 할 수 있습니다.

  • 경찰 제출이 구현 정의 또는 정의되지 않은 동작에 의존하는 경우 시스템에서 (확인 가능) 작동하는 균열 만 찾으면됩니다.

  • 각 균열은 강도 실에서 별도의 답변에 속합니다.

  • 잘못된 크래킹 시도를 게시하면 30 분 동안 해당 특정 크래킹이 크래킹되지 않습니다.

  • 당신은 당신 자신의 제출물을 해독 할 수 없습니다.

예

Python 2.7, 사용자 별 22 바이트

1

과

18

리더 보드

안전한 제출

  1. CJAM, eBusiness에서 21 바이트
  2. C ++, 148 바이트 (tucuxi)
  3. C ++, Vi에 의한 233 (?) 바이트

미결제 제출

이 스택 스 니펫을 사용하여 아직 크랙되지 않은 답변 목록을 얻을 수 있습니다.

function g(p){$.getJSON('//api.stackexchange.com/2.2/questions/51068/answers?page='+p+'&pagesize=100&order=desc&sort=creation&site=codegolf&filter=!.Fjs-H6J36w0DtV5A_ZMzR7bRqt1e',function(s){s.items.map(function(a){var h=$('<div/>').html(a.body).children().first().text();if(!/cracked/i.test(h)&&(typeof a.comments=='undefined'||a.comments.filter(function(b){var c=$('<div/>').html(b.body);return /^cracked/i.test(c.text())||c.find('a').filter(function(){return /cracked/i.test($(this).text())}).length>0}).length==0)){var m=/^\s*((?:[^,(\s]|\s+[^-,(\s])+)\s*(?:[,(]|\s-).*?([0-9]+)/.exec(h);$('<tr/>').append($('<td/>').append($('<a/>').text(m?m[1]:h).attr('href',a.link)),$('<td class="score"/>').text(m?m[2]:'?'),$('<td/>').append($('<a/>').text(a.owner.display_name).attr('href',a.owner.link))).appendTo('#listcontent');}});if(s.length==100)g(p+1);});}g(1);
table th, table td {padding: 5px} th {text-align: left} .score {text-align: right} table a {display:block}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><table><tr><th>Language</th><th class="score">Length</th><th>User</th></tr><tbody id="listcontent"></tbody></table>


해시 함수가 2 ^ 128-1보다 큰 숫자를 잘못 반환하면 제출이 무효화되거나 단순히 결과를 모듈로 2 ^ 128로 가져 옵니까?
— 마틴 엔더

@ MartinBüttner : 그렇습니다. 모듈로 2 ^ 128을 가져와야합니다.
— Dennis

1
@Scimonster가 요구 사항을 충족하지 못함 (최대 2 ^ 30 비트 입력, 128 비트 출력)
— CodeInChaos

1
경찰과 강도는 대개 반대 방향으로 가지 않습니까?
— haneefmubarak 2018 년

2
아마도 우리는 제출물에 예제 해시를 포함해야한다는 규칙을 가지고있을 수 있습니다. 구현 자와 크래킹을 비교하는 결과를 얻기 위해 제출자가 선택한 프로그래밍 언어를 실행해야한다는 것은 매우 성가신 일입니다.
— aaaaaaaaaaaa

답변:


6

CJam, 21 바이트

1q3*{i+_E_#*^26_#)%}/

바이트 열을 입력으로받습니다.

의사 코드에서 :

hash = 1
3 times:
    for i in input:
        hash = hash + i
        hash = hash xor hash * 14^14
        hash = hash mod (26^26 + 1)
output hash

해시 예 :

""(빈 문자열)-> 1
"테스트"-> 2607833638733409808360080023081587841
"test"-> 363640467424586895504738713637444713

그것은 간단한면에 약간있을 수 있으며, 출력 범위는 122 비트 이상이며, 트리플 반복 강화는 매번 똑같은 일을하기 때문에 이미 약간 깨졌습니다. 반복은 완전히 중단됩니다. 그러나 짧고 너무 안전하다는 재미는 없습니다.


다른 CJam 게시물과 같은 C 버전이 있습니까?
— Vi.

@Vi. 아니요, 아직은 아닙니다. 나는 C에서 bigint를 다루지 않았다. 표준 라이브러리가 있습니까?
— aaaaaaaaaaaa

GMP ?
— Vi.


1
@ Agawa001 용어가 섞여 있습니다. 트리플 패스 스펀지 함수 해시 알고리즘입니다. 시저 암호는 내부 상태가없는 하나의 특정 암호화 알고리즘입니다.
— aaaaaaaaaaaa

7

파이썬, 109 바이트 [ 갈라짐 , 다시 ]

def f(n,h=42,m=2**128):
 while n:h+=n&~-m;n>>=128;h+=h<<10;h^=h>>6;h%=m
 h+=h<<3;h^=h>>11;h+=h<<15;return h%m

나는 Jenkins의 한 번에 한 번에 한 함수를 그대로 구현하려고 시도했지만 유일한 차이는 시드와 비트 수입니다.

재미있는 사실 : Perl은 어느 시점에서 Jenkins의 해시를 사용했습니다 .

싸개

print(f(int(input())))

예

>>> f(0)
12386682
>>> f(1)
13184902071
>>> f(2**128-1)
132946164914354994014709093274101144634
>>> f(2**128)
13002544814292
>>> f(2**128+1)
13337372262951
>>> f(2**(2**20))
290510273231835581372700072767153076167



6

C ++, 148 바이트

typedef __uint128_t U;U h(char*b,U n,U&o){U a=0x243f6a8885a308d,p=0x100000001b3;for(o=a;n--;)for(U i=27;--i;){o=(o<<i)|(o>>(128-i));o*=p;o^=b[n];}}

__uint128_t 는 GCC 확장이며 예상대로 작동합니다. 해시는 반복적 FNV 해시 (각 a16 진수의 Pi의 첫 번째 숫자 이지만 소수를 빌려 왔습니다 )를 반복하여 각 반복이 시작될 때 sha1과 같은 회전을 기반으로합니다. 으로 컴파일 -O3하고 10MB 파일을 해시하는 데 2 ​​초가 걸리지 않으므로 내부 루프에서 반복을 올릴 수있는 여백이 여전히 있습니다.하지만 오늘 관대합니다.

크래킹의 즐거움을 위해 추방 된 (변수 이름 변경, 설명 추가, 공백 및 괄호 쌍) :

typedef __uint128_t U;
U h(char* input, U inputLength, U &output){
    U a=0x243f6a8885a308d,p=0x100000001b3;    
    for(output=a;inputLength--;) {   // initialize output, consume input
        for(U i=27;--i;) {                          // evil inner loop
            output = (output<<i)|(output>>(128-i)); // variable roll 
            output *= p;                            // FNV hash steps
            output ^= input[inputLength];        
        }
    }
    // computed hash now available in output
}

골프 제안은 환영합니다 (기초에 따라 코드를 개선하지 않아도).

편집 : 수정되지 않은 코드의 오타 수정 (골프 버전은 변경되지 않음).


o초기화되지 않은 것 같습니다. 어디에 output선언되어 있습니까? 아니면 o입니다 output?
— Vi.

에 대해서도 동일합니다 n. 실제로 "제거되지 않은"코드가 실행되도록 확인 했습니까?
— Vi.

무차별 범을 시작 ...
— Vi.

3 라운드 버전조차 쉽지 않습니다.
— Vi.

@Vi. 수정되지 않은 버전 수정-더 이상 확인하지 않아서 죄송합니다. 나는 그 내부 루프를 자랑스럽게 생각합니다. U i=81;i-=3런타임 비용이 많이 들지 않으면 서 훨씬 더 사악했을 수 있습니다.
— tucuxi

5

CJam, 44 바이트 [ 크랙 ]

lW%600/_z]{JfbDbGK#%GC#[md\]}%z~Bb4G#%\+GC#b

입력은 10 진입니다.

CJam은 느립니다. 일부 컴퓨터에서 1 초 안에 실행되기를 바랍니다.

설명

lW%600/            e# Reverse, and split into chunks with size 600.
_z                 e# Duplicate and swap the two dimensions.
]{                 e# For both versions or the array:
    JfbDb          e# Sum of S[i][j]*13^i*19^j, where S is the character values,
                   e# and the indices are from right to left, starting at 0.
    GK#%GC#[md\]   e# Get the last 32+48 bits.
}%
z~                 e# Say the results are A, B, C, D, where A and C are 32 bits.
Bb4G#%             e# E = the last 32 bits of A * 11 + C.
\+GC#b             e# Output E, B, D concatenated in binary.

글쎄, 이차원적인 것들은 약한 것 같았다 그러나 내가하는 일에 관계없이 잠시 후에 실행할 수 없으므로 느린 코드를 마침내 제거했습니다.

이진 비트와 더 높은 기준을 사용하면 더 좋습니다.

C 버전

__uint128_t hash(unsigned char* s){
    __uint128_t a=0,b=0;
    __uint128_t ar=0;
    __uint128_t v[600];
    int l=0,j=strlen(s);
    memset(v,0,sizeof v);
    for(int i=0;i<j;i++){
        if(i%600)
            ar*=19;
        else{
            a=(a+ar)*13;
            ar=0;
        }
        if(i%600>l)
            l=i%600;
        v[i%600]=v[i%600]*19+s[j-i-1];
        ar+=s[j-i-1];
    }
    for(int i=0;i<=l;i++)
        b=b*13+v[i];
    a+=ar;
    return (((a>>48)*11+(b>>48))<<96)
        +((a&0xffffffffffffull)<<48)
        +(b&0xffffffffffffull);
}

설명을 추가해 주시겠습니까? 모두가 CJam을 알고있는 것은 아닙니다.
— orlp

@orlp 편집 ...
— jimmy23013 2016 년

내 컴퓨터에서 0.4 초가 걸리므로 허용 범위 내에 있습니다.
— Dennis

A, B, C 등은 무엇입니까? 일부 매트릭스? 어느 치수? C로 쉽게 구현할 수 있습니까?
— Vi.

1
금이 믿습니다.
— Sp3000

5

C ++, 182 자 (+ 보일러 문자 약 51 자)

h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=buf[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}

보일러 플레이트 :

void hash(const unsigned char* buf, size_t len, unsigned long long *hash1, unsigned long long *hash2)
{
    unsigned long long &h=*hash1;
    unsigned long long &j=*hash2;
    size_t l = len;
    const unsigned char* b = buf;

    // code here
}

골프 기능을 갖춘 실행 가능한 프로그램

#include <stdio.h>

// The next line is 227 characters long
int hash(char*b,int l,long long&h,long long&j){h=0xC0CC3051F486B191;j=0x9A318B5A176B8125;char q=0;for(int i=0;i<l;++i){char w=b[i];h+=((w<<27)*257);j^=(h+0x5233);h+=0xAA02129953CC12C3*(j>>32);j^=(w+0x134)*(q-0x16C552F34);q=w;}}

int main() {
    char buf[1024];
    int l  = fread(buf, 1, 1024, stdin);
    long long q, w;
    hash(buf, l, q, w);
    printf("%016llX%016llX\n", q, w);
}

2
함수 선언 등이 문자 수에 포함된다고 생각합니다.
— Ypnypn

@Ypnypn, 골프 다운 함수 선언에서 문자를 세었습니다.
— Vi.

출력 해시는 무엇입니까? 나는 그것이 ((h << 64) | j)라고 가정합니다.
— tucuxi 2016 년

예. 또는 한 쌍의 64 비트 숫자입니다. 나는 __uint128_t이것을 구현 한 후에 만 알았습니다 .
— Vi.

1
@Dennis, Done.󠀠
— Vi.

4

피시스, 8 금이

sv_`.lhQ

온라인으로 사용해보십시오

어리석은 대답은 대부분의 사람들이 Pyth를 읽을 수 없기 때문에 어떻게 작동하는지 설명하겠습니다. 이것은 1의 자연 로그에 입력을 더한 다음 문자열로 변환합니다. 해당 문자열을 반대로 한 다음 평가 한 다음 정수로 변환합니다.

파이썬 번역은 다음과 같습니다.

import math
n = eval(input()) + 1
rev = str(math.log(n))[::-1]
print(int(eval(rev)))


4

Python 3, 216 바이트 [ 크랙 ]

def f(m):
 h=1;p=[2]+[n for n in range(2,102)if 2**n%n==2];l=len(bin(m))-2;*b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])
 while b:
  h*=h
  for P in p:
   if b:h=h*P**b.pop()%0xb6ee45a9012d1718f626305a971e6a21
 return h

사양과의 비 호환성으로 인해 적어도 하나의 사소한 취약점에 대해 생각할 수 있지만, 이것이 최소한 무차별적인 증거라고 생각합니다. 다른 것들 중에서도 처음 천만개의 해시를 확인했습니다.

골프 측면에서 이것은 Python 2에서 더 짧을 것이지만 효율성을 위해 약간의 바이트를 희생했습니다 (아마도 이길 수 없기 때문에).

편집 : 이것은 Very Smooth Hash 를 구현하려는 시도 였지만 불행히도 128 비트는 너무 작습니다.

싸개

print(f(int(input())))

예

>>> f(0)
2
>>> f(123456789)
228513724611896947508835241717884330242
>>> f(2**(2**19)-1)
186113086034861070379984115740337348649
>>> f(2**(2**19))
1336078

코드 설명

def f(m):
 h=1                                             # Start hash at 1
 p=[2]+[n for n in range(2,102)if 2**n%n==2]     # p = primes from 2 to 101
 l=len(bin(m))-2                                 # l = bit-length of m (input)
 *b,=map(int,bin((l<<(l+25)//26*26)+m)[2:])      # Convert bits to list, padding to
                                                 # a multiple of 26 then adding the
                                                 # bit-length at the front

 while b:                                        # For each round
  h*=h                                           # Square the hash
  for P in p:                                    # For each prime in 2 ... 101
   if b:h=(h*P**b.pop()                          # Multiply by prime^bit, popping
                                                 # the bit from the back of the list
           %0xb6ee45a9012d1718f626305a971e6a21)  # Take mod large number

 return h                                        # Return hash

패딩의 예 f(6):

[1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0]

(len 3)(------------------ 23 zeroes for padding -------------------------)(input 6)
       (---------------------------- length 26 total ------------------------------)


4

C, 87 바이트 [ 균열 ]

이것은 완전한 프로그램입니다. 래퍼가 필요하지 않습니다. stdin을 통한 이진 입력을 허용하고 16 진 해시를 stdout에 출력합니다.

c;p;q;main(){while((c=getchar())+1)p=p*'foo+'+q+c,q=q*'bar/'+p;printf("%08x%08x",p,q);}

이것은 64 비트 해시 만 계산하므로 여기서 약간의 도박을하고 있습니다.

경우 사람이, 두 상수를 궁금있어 'foo+'및 'bar/'주요 번호 1718578987 및 1650553391입니다.


예 :

선행 0을 무시합니다.

echo -ne '\x00\x00\x00\x00' |./hash
0000000000000000

싱글 바이트 입력 :

echo -ne '\x01' |./hash
0000000100000001
echo -ne '\xff' |./hash
000000ff000000ff

멀티 바이트 입력 :

echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15c
echo -ne 'Hello, World' |./hash
04f1a7412b17b86c

'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'와 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'와 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'는 어떻게 행동합니까?
— Ismael Miguel

1
foo|(d5c9bef71d4f5d1b) 및 foo\(d5c9bef71d4f5d1b)는 매우 유사한 해시를 생성 합니다.
— Ismael Miguel

1
파산 !!! \x00그리고 \x00\x00!
— Ismael Miguel

1
채팅 댓글을 바탕으로 아직 이것이 크랙되지 않았다고 생각합니까? upvoted 의견은 깨지지 않은 해시를 감추고있는 사람들에게는 혼란 스러울 수 있으므로 두 번 확인하십시오.
— Sp3000


3

J-39 바이트- 금이 간

문자열을 입력으로 받아서 정수 <2 128을 반환하는 함수 . 함수의 이름을 유효하게 지정해야한다고 가정하므로 익명 함수를 제출할 수 있으면 다른 3자를 삭제하십시오.

H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]

상형 문자를 읽지 않는 사람들을 위해 여기 내가하는 일에 대한 요약이 있습니다.

  • a=.(2^128x)&|@^/@이것은 서브 루틴 *으로 숫자 배열을 취한 다음 지수를 전력 타워로 취급합니다. 여기서 지수는 mod 2 128 입니다. "파워 타워"는 입력 3 4 5 6을 주면 계산 한다는 의미 3 ^ (4 ^ (5 ^ 6))입니다.
  • (".p:@+5,9:)a이 함수는 문자열을 가져 와서 숫자 N으로 변환 한 다음 ( n +5) 번째 및 ( n +9) 번째 소수를 계산 한 다음 a이전부터 시작합니다. 즉 우리가 찾을 수있다 p(n+5) ^ p(n+9)2 모드 128 곳 p(k)은 IS k번째 수상.
  • H=:_8...\(a...)]입력의 8 문자 서브 블록에 대해 위 기능을 수행 한 다음 a모든 결과를 함께 수행하고 결과 해시 함수를 호출하십시오 H. J의 " k-th prime"기능이 p(k)> 2 31을 초과 할 때 ( 즉 k=105097564, 가장 큰 안전) 8 문자를 사용 합니다 k.

샘플 출력이 있습니다. 당신은 온라인이 자신을 시도 할 수 tryj.tk ,하지만 난 정말에서 인터프리터 다운로드하여 집에서이 일을하는 것이 좋습니다 Jsoftware을 .

   H=:_8(".p:@+5,9:)a\(a=.(2^128x)&|@^/@)]
   H '88'
278718804776827770823441490977679256075
   H '0'
201538126434611150798503956371773
   H '1'
139288917338851014461418017489467720433
   H '2'
286827977638262502014244740270529967555
   H '3'
295470173585320512295453937212042446551
   30$'0123456789'  NB. a 30 character string
012345678901234567890123456789
   H 30$'0123456789'
75387099856019963684383893584499026337
   H 80$'0123456789'
268423413606061336240992836334135810465

* 기술적으로는 그 자체로는 기능이 아니며 다른 기능에 연결되어 출력에 작용합니다. 그러나 이것은 개념적 차이가 아닌 J의 의미 론적 문제입니다. 프로그램 흐름은 위에서 설명한대로입니다.



2

파이썬 3, 118 바이트 [ 금 ]

def H(I):
    o=0;n=3;M=1<<128
    for c in I:i=ord(c);o=(o<<i^o^i^n^0x9bb90058bcf52d3276a7bf07bcb279b7)%M;n=n*n%M
    return o

들여 쓰기는 단일 탭입니다. 간단한 해시, 아직 철저히 테스트하지는 않았습니다.

다음과 같이 전화하십시오 :

print(H("123456789"))

결과: 73117705077050518159191803746489514685


알고리즘에서 사용하기 위해 입력 정수를 문자열로 어떻게 변환해야합니까?
— feersum

@ feersum base-10 문자열은 내가 테스트 한 것입니다. 그것은 아무것도 사용하지 않지만 ord(c)그래도, 그래서 정말 :) 할 것입니다 문자열 (NUL 문자 같은 것들을 제외하고, 나는 정말 쉽게 그 메이크업 해시 충돌을 생각 그래서 스틱을 0-9 문자열..)
— tomsmeding

1
그것을 깨뜨렸다 : codegolf.stackexchange.com/a/51160/41288 . "10000"및 "20000"과 같은 문자열은 매우 가까운 해시를 생성 함을 관찰함으로써 시작됩니다. 점점 더 많은 제로를 가지고 놀기 시작했으며, 128 정도가 지나면 모든 숫자 + k * 4 제로 반복은 k에 관계없이 동일한 해시를 반환합니다.
— tucuxi 2016 년

@tucuxi는 이미 벌하지한다고 생각 너무 열심히; 사소한 것이 아니지만 누군가 어쨌든 그것을 깨뜨린 것이 기쁘다. 잘 했어.
— tomsmed

2

C ++, 239 바이트

내 첫 번째 코드 골프! [ 부드럽게 부탁드립니다 ]

#define r(a,b) ((a<<b)|(a>>(64-b)))
typedef uint64_t I;I f(I*q, I n, I&h){h=0;for(I i=n;--i;)h=r(h^(r(q[i]*0x87c37b91114253d5,31)*0x4cf5ad432745937f),31)*5+0x52dce729;h^=(h>>33)*0xff51afd7ed558ccd;h^=(h>>33)*0xc4ceb9fe1a85ec53;h^=(h>>33);}

언 골프 버전 :

I f(I* q, I n, I& h) // input, length and output
{
    h = 0; // initialize hashes
    for (I i=n;--i;)
    {
        q[i] *= 0x87c37b91114253d5;
        q[i]  = rotl(q[i], 31);
        q[i] *= 0x4cf5ad432745937f;

        h ^= q[i]; // merge the block with hash

        h *= rotl(h, 31);
        h = h * 5 + 0x52dce729;
    }
    h ^= h>>33;
    h *= 0xff51afd7ed558ccd;
    h ^= h>>33;
    h *= 0xc4ceb9fe1a85ec53; // avalanche!
    h ^= h>>33;
}

최고의 해시가 아니며 존재하는 가장 짧은 코드도 아닙니다. 골프 팁을 받아들이고 개선하기를 바라고 있습니다!

싸개

아마도 세계 최고는 아니지만 랩퍼입니다.

I input[500];

int main()
{
    string s;
    getline(cin, s);
    memcpy(input, s.c_str(), s.length());
    I output;
    f(input, 500, output);
    cout << hex << output << endl;
}

2
단단해 보이지만 64 비트이면 무차별하게 적용될 수 있습니다. ~ sqrt (n) 테스트에서 n 개의 총 출력 중 충돌을 발견 할 확률은 약 50 %입니다. 2 ^ 32 시도는 현대 PC에는 그다지 중요하지 않습니다.
— tucuxi 2016 년

래퍼에는 헤더가 포함되어 있지 않으며 일반적으로 많은 해시로 이어집니다.
— Vi.

해시 샘플을 제공하십시오. 나를 위해 "3"과 "33"은 481c27f26cba06cf (이 래퍼 사용)로 이어집니다.
— Vi.

금 : codegolf.stackexchange.com/a/51215/41288 . @Vi 직전에 의심됩니다. 왜 그렇게 많은 해시가 같은지 알아 냈습니다.
— tucuxi 2016 년

1
적절한 충돌 (버그 사용 안함) : printf '33333333\x40\xF3\x32\xD6\x56\x91\xCA\x66' | ./hash7_-> a4baea17243177fd; printf '33333333\x77\x39\xF3\x82\x93\xDE\xA7\x2F' | ./hash7_-> a4baea17243177fd. bruteforcer는 여기서 다른 64 비트 해시와 비교하여 충돌이 훨씬 빠릅니다.
— Vi.

2

Java, 299 291 282 바이트, 크랙 됨.

import java.math.*;class H{public static void main(String[]a){BigInteger i=new java.util.Scanner(System.in).nextBigInteger();System.out.print(BigInteger.valueOf(i.bitCount()*i.bitLength()+1).add(i.mod(BigInteger.valueOf(Long.MAX_VALUE))).modPow(i,BigInteger.valueOf(2).pow(128)));}}

BigIntegers에서 일부 연산을 수행 한 다음 결과 modulo 2 128 을 가져옵니다 .


이것을 어떻게 실행합니까? Ideone은 컴파일을 거부합니다.
— 마틴 엔더

1
클래스 이름을 "Main"으로 바꾸거나 첫 번째 "public"키워드 (두 번째 키워드는 아님)를 제거하여 Ideone에서이를 실행할 수 있습니다. 어느 쪽이든 작동합니다.
— SuperJedi224


1
@ SuperJedi224 왜 첫 번째 public문자를 제거하여 7 자를 저장 하지 않겠습니까 ?
— user253751 2018 년

@immibis 왜냐하면 Eclipse에서 제대로 작동한다고 생각하지 않습니다. 그래도해볼 게요. 편집 : 나는 그렇게 생각합니다. 놀랍습니다.
— SuperJedi224

2

C, 128 바이트 [ 갈라짐 ]

p;q;r;s;main(c){while((c=getchar())+1)p=p*'foo+'+s^c,q=q*'bar/'+p,r=r*'qux3'^q,s=s*'zipO'+p;printf("%08x%08x%08x%08x",p,q,r,s);}

이것은 내 마지막 노력 (Vi.에서 크랙) 과 거의 동일한 알고리즘 이지만 이제는 적절한 128 비트 해시를 생성하기에 충분한 햄스터 휠이 있습니다.

코드의 4 가지 주요 상수는 다음과 같습니다.

'foo+' = 1718578987
'bar/' = 1650553391
'qux3' = 1903523891
'zipO' = 2053730383

이전과 마찬가지로이 프로그램은 래퍼가 필요없는 완전한 프로그램입니다. 정수 I 은 원시 이진 데이터 (big-endian)로 stdin을 통해 입력되며 해시 O 는 16 진으로 stdout에 인쇄됩니다. I의 선행 0 은 무시됩니다.

예 :

echo -ne '\x00' |./hash
00000000000000000000000000000000
echo -ne '\x00\x00' |./hash
00000000000000000000000000000000
echo -ne '\x01' |./hash
00000001000000010000000100000001
echo -ne 'A' |./hash
00000041000000410000004100000041
echo -ne '\x01\x01' |./hash
666f6f2dc8d0e15cb9a5996fe0d8df7c
echo -ne 'Hello, World' |./hash
da0ba2857116440a9bee5bb70d58cd6a


귀하의 예가 바로 충돌을 보여주지 않았습니까 (처음 두 개)?
— mbomb007

@ mbomb007 아니요. 입력은 0에서 2 ^ (2 ^ 30) 사이의 숫자입니다. 0x00과 0x0000은 모두 0과 같으므로 동일한 출력을 생성합니다.
— squeamish ossifrage

2

C, 122 바이트 [ 크랙 ]

long long x,y,p;main(c){for(c=9;c|p%97;c=getchar()+1)for(++p;c--;)x=x*'[3QQ'+p,y^=x^=y^=c*x;printf("%016llx%016llx",x,y);}

중첩 루프, 반이중 LCG 및 변수 스와핑. 무엇을 사랑하지거야?

여기에 놀 수있는 ungolf'd 버전이 있습니다.

long long x,y,p;

int main(int c){
    // Start with a small number of iterations to
    //   get the state hashes good and mixed because initializing takes space
    // Then, until we reach the end of input (EOF+1 == 0)
    //   and a position that's a multiple of 97
    for (c=9;c|p%97;c=getchar()+1) {

        // For each input c(haracter) ASCII value, iterate down to zero
        for (++p;c--;) {

            // x will act like a LCG with a prime multiple
            //   partially affected by the current input position
            // The string '[3QQ' is the prime number 0x5B335151
            x=x*'[3QQ'+p;

            // Mix the result of x with the decrementing character
            y^=c*x;

            // Swap the x and y buffers
            y^=x^=y;
        }
    }

    // Full 128-bit output
    printf("%016llx%016llx",x,y);
    return 0;
}

이것은 STDIN에서 읽고 STDOUT으로 인쇄하는 완전히 독립적 인 프로그램입니다.

예:

> echo -n "Hello world" | ./golfhash
b3faef341f70c5ad6eed4c33e1b55ca7

> echo -n "" | ./golfhash
69c761806803f70154a7f816eb3835fb

> echo -n "a" | ./golfhash
5f0e7e5303cfcc5ecb644cddc90547ed

> echo -n "c" | ./golfhash
e64e173ed4415f7dae81aae0137c47e5

간단한 벤치 마크에서는 약 3MB / s의 텍스트 데이터를 해시합니다. 해시 속도는 입력 데이터 자체에 따라 다르므로 아마도 고려해야합니다.



1

PHP 4.1, 66 바이트 [ 크랙 ]

난 그냥 워밍업 해요.

나는 당신이이 근심을 발견하기를 바랍니다.

<?for($l=strlen($b.=$a*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

999999999999999999999999999. 나는 대형으로 숫자를 시도했습니다
출력은 2 내 것 같았다 128 범위.


register_globals지시문 때문에 PHP 4.1이 필요 합니다.

세션, POST, GET, REQUEST 및 쿠키에서 로컬 변수를 자동으로 생성하여 작동합니다.

키를 사용합니다 a. (EG :을 통해 액세스 http://localhost/file.php?a=<number>).

PHP 4.2 이상으로 테스트하려면 다음을 시도하십시오.

<?for($l=strlen($b.=$a=$_REQUEST['a']*1);$i<40;$o.=+$b[+$i]^"$a"/$a,$i++);echo$o;

이 버전은 POST 및 GET에서만 작동합니다.


출력 예 :

0 -> 0000000000000000000000000000000000000000
9 -> 8111111111111111111111111111111111111111
9999 -> 8888111111111111111111111111111111111111
1234567890 -> 0325476981111111111111111111111111111111
99999999999999999999999999999999999999999999999999999999999999999999999999999999 -> 0111191111111111111111111111111111111111

(동일한 해시를 생성하는 숫자가 있음을 확신합니다).



1

C, 134 바이트, 금이 간

이것은 완전한 C 프로그램입니다.

long long i=0,a=0,e=1,v,r;main(){for(;i++<323228500;r=(e?(scanf("%c",&v),e=v>'/'&&v<':',v):(a=(a+1)*7)*(7+r)));printf("0x%llx\n", r);}

그것이하는 일 : 바이트 배열로 입력을 취하고 끝에 임의의 (그러나 결정적) 바이트를 추가하여 길이를 약 2 2 30 (약간 더) 으로 만드는 것이 아이디어입니다 . 구현은 바이트 단위로 입력을 읽고 숫자가 아닌 첫 번째 문자를 찾으면 의사 난수 데이터 사용을 시작합니다.

내장 PRNG가 허용되지 않으므로 직접 구현했습니다.

코드를 더 짧게 만드는 정의되지 않은 / 구현 정의 된 동작이 있습니다 (최종 값은 부호가 없어야하며 다른 값에는 다른 유형을 사용해야합니다). 그리고 C에서 128 비트 값을 사용할 수 없었습니다.

long long i = 0, prand = 0, notEndOfInput = 1, in, hash;

main() {
    for (; i++ < 323228500;) {
        if (notEndOfInput) {
            scanf("%c", &in);
            notEndOfInput = in >= '0' && in <= '9';
            hash = in;
        } else {
            prand = (prand + 1)*7;
            hash = prand*(7 + hash);
        }
    }
    printf("0x%llx\n", hash);
}


1

파이썬 2.X-139 바이트 [[ Cracked ]]

이것은 다른 모든 (LOOP, XOR, SHIFT, ADD) 해시와 매우 유사합니다. 당신의 포인트 강도를 얻을 와서;)이 하나가 해결 된 후 더 열심히 만들 것입니다.

M=2**128
def H(I):
 A=[1337,8917,14491,71917];O=M-I%M
 for z in range(73):
  O^=A[z%4]**(9+I%9);O>>=3;O+=9+I**(A[z%4]%A[O%4]);O%=M
 return O

래퍼 (16 진수라고도하는 16 진수의 인수 하나만 예상 됨) :

import sys
if __name__ == '__main__':
 print hex(H(long(sys.argv[1], 16)))[2:][:-1].upper()


1
또한이 항목이 OP의 사양을 충족하는지 확실하지 않습니다. 내 컴퓨터에서는 큰 입력에서 기능이 여러 초 걸립니다. 예를 들어 H(2**(2**10))약 8 초 또는 9 초가 H(2**(2**12))걸리고 약 29 초가 H(2**(2**14))걸리고 2 분이 걸렸습니다.
— mathmandan 2016 년

당신은 절대적으로 맞습니다. 분명히 더 큰 입력 타이밍을 테스트해야합니다. 또한 해당 근무 시간이 추가 된 후 자체 테스트를 실행하는 것을 잊어 버린 것 같습니다. 원래 버전 (게시하기 전에) 변화 선수 그리고 테스트 "처음 100000 개 정수에 더 충돌"내 전달되지 않았다 : /
— 의아해

1

파이썬 2.7-161 바이트 [[ Cracked ]]

글을 게시하기 전에 첫 번째 해시 함수를 쓸모없는 버전으로 변경 했으므로 비슷한 구조의 다른 버전을 게시 할 것이라고 생각합니다. 이번에는 사소한 충돌에 대해 테스트했으며 가능한 대부분의 입력 크기를 테스트했습니다.

A=2**128;B=[3,5,7,11,13,17,19]
def H(i):
 o=i/A
 for r in range(9+B[i%7]):
  v=B[i%7];i=(i+o)/2;o=o>>v|o<<128-v;o+=(9+o%6)**B[r%6];o^=i%(B[r%6]*v);o%=A
 return o

랩퍼 (바이트 카운트에 포함되지 않음)

import sys
if __name__ == '__main__':
 arg = long(sys.argv[1].strip(), 16)
 print hex(H(arg))[2:][:-1].upper()

실행 예 (입력은 항상 16 진수) :

$ python crypt2.py 1
3984F42BC8371703DB8614A78581A167
$ python crypt2.py 10
589F1156882C1EA197597C9BF95B9D78
$ python crypt2.py 100
335920C70837FAF2905657F85CBC6FEA
$ python crypt2.py 1000
B2686CA7CAD9FC323ABF9BD695E8B013
$ python crypt2.py 1000AAAA
8B8959B3DB0906CE440CD44CC62B52DB


잘 했어 지미 :)
— 의아해

1

루비, 90 바이트

def H(s);i=823542;s.each_byte{|x|i=(i*(x+1)+s.length).to_s.reverse.to_i%(2**128)};i;end

실제 해시를 보지 않고 만든 매우 무작위 해시 알고리즘 ... 좋은지 모릅니다. 문자열을 입력으로 사용합니다.

싸개:

def buildString(i)
  if(i>255)
    buildString(i/256)+(i%256).chr
  else
    i.chr
  end
end 
puts H buildString gets

질문에 필요한 래퍼를 제공해 주시겠습니까?
— Dennis

입력 형식은 무엇입니까? 나는 숫자로 시도했지만 말한다 comparison of String with 255 failed (ArgumentError).
— jimmy23013

H는 문자열을 가져오고 Build string은 OP에 필요한 수를 가져 와서 문자열로 변환합니다.
— MegaTom

gets.to_i래퍼에 필요하다고 생각합니다 .
— jimmy23013 2016 년


0

Mathematica, 89 바이트, 금이 간

Last@CellularAutomaton[(a=Mod)[#^2,256],{#~IntegerDigits~2,0},{#~a~99,128}]~FromDigits~2&

최단이 아닙니다.


3
Mathematica없이 어떻게 이것을 실행합니까? "x86 또는 x64 플랫폼에서 또는 웹 브라우저에서 실행할 수있는 비어있는 컴파일러 / 인터프리터가 있어야합니다."
— Martin Ender



0

PHP, 79 바이트 (크랙. 주석 포함) :

echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);

이것은 PHP에서 유형 변환을 통해 많은 무서운 일을하므로 예측하기가 어렵습니다. 그러나 가장 짧거나 읽을 수없는 대답은 아닙니다.

이를 실행하려면 PHP4 를 사용 하고 전역을 등록 하거나 (? i = 123 사용) 명령 줄을 사용하십시오.

php -r "$i = 123.45; echo (('.'.str_replace('.',M_E*$i,$i/pi()))*substr(pi(),2,$i%20))+deg2rad($i);"

5
해시의 출력 값은 부동 소수점으로 보입니다. 그리고 3000000000000000000000000000000000000000000001과 3000000000000000000000000000000000000000000000에 대해서도 동일합니다
— .

0

C #-393 바이트 크랙

using System;class P{static void Main(string[]a){int l=a[0].Length;l=l%8==0?l/8:l/8+1;var b=new byte[l][];for(int i=0;i<l;i++){b[i]=new byte[8];};int j=l-1,k=7;for(int i=0;i<a[0].Length;i++){b[j][k]=Convert.ToByte(""+a[0][i],16);k--;if((i+1)%8==0){j--;k=7;}}var c=0xcbf29ce484222325;for(int i=0;i<l;i++){for(int o=0;o<8;o++){c^=b[i][o];c*=0x100000001b3;}}Console.WriteLine(c.ToString("X"));}}

언 골프 드 :

using System;
class P
{
    static void Main(string[]a)
    {
      int l = a[0].Length;
      l = l % 8 == 0 ? l / 8 : l / 8 + 1;
      var b = new byte[l][];
      for (int i = 0; i < l; i++) { b[i] = new byte[8]; };
      int j = l-1, k = 7;
      for (int i = 0; i < a[0].Length; i++)
      {
        b[j][k] = Convert.ToByte(""+a[0][i], 16);
        k--;
        if((i+1) % 8 == 0)
        {
          j--;
          k = 7;
        }
      }
      var c = 0xcbf29ce484222325;
      for (int i = 0; i < l; i++)
      {
        for (int o = 0; o < 8; o++)
        {
          c ^= b[i][o];
          c *= 0x100000001b3;
        }
      }
      Console.WriteLine(c.ToString("X"));
    }
}

나는 내 인생에서 암호화 또는 해싱을 만지지 않았으므로 부드럽게하십시오 :)

FNV-1a 의 간단한 구현입니다.입력에서 일부 피벗 회전을 사용 해시 . 나는 이것을하는 더 좋은 방법이 있다고 확신하지만 이것이 내가 할 수있는 최선입니다.

긴 입력에서 약간의 메모리를 사용할 수 있습니다.


깨짐 : codegolf.stackexchange.com/a/51277/101 패딩에 결함이있는 것 외에 이것은 암호화 해시가 아니며이를 해독 할 수있는 방법이 너무 많습니다.
— aaaaaaaaaaaa

0

파이썬 2, 115 바이트 [ 이미 깨져! ]

자, 마지막 노력입니다. 마지막 줄 바꿈이 필요하지 않으므로 115 바이트 만 가능합니다.

h,m,s=1,0,raw_input()
for c in[9+int(s[x:x+197])for x in range(0,len(s),197)]:h+=pow(c,257,99**99+52)
print h%4**64

이것은 stdin에 십진 정수를 입력하고 stdout에 십진 해시 값을 인쇄하는 완전한 프로그램입니다. 여분의 선행 0은 다른 해시 값을 초래하므로 입력에 아무것도 없다고 가정합니다.

이것은 모듈 식 지수를 통해 197 자리의 입력 숫자 청크를 채워서 작동합니다. 일부 언어와 달리이 int()함수는 항상 기본 10이 기본이므로 int('077')63이 아닌 77입니다.

샘플 출력 :

$ python hash.py <<<"0"
340076608891873865874583117084537586383

$ python hash.py <<<"1"
113151740989667135385395820806955292270

$ python hash.py <<<"2"
306634563913148482696255393435459032089

$ python hash.py <<<"42"
321865481646913829448911631298776772679

$ time python hash.py <<<`python <<<"print 2**(2**19)"`
233526113491758434358093601138224122227

real    0m0.890s   <-- (Close, but fast enough)
user    0m0.860s
sys     0m0.027s

1
블록 순서를 사용하지 않았습니다 ... Cracked .
— jimmy23013

어. 나는 줄 :-(
— squeamish ossifrage
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.