C #에서 SHA1 알고리즘을 사용한 해싱


84

byte[]사용하여 SHA1알고리즘을 사용하여 주어진 배열 을 해시하고 싶습니다 SHA1Managed. 해시는 단위 테스트에서 올 것이다. 예상 해시는 (대소 문자 구분)입니다.
byte[]
0d71ee4472658cd5874c5578410a9d8611fc9aef

이것을 어떻게 달성 할 수 있습니까?

public string Hash(byte [] temp)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {

    }
}

1
제외 된 해시는 16 진수 값이므로 대소 문자를 구분하는지 여부는 중요하지 않습니다. 예hex(e) == hex(E)
jAC

답변:


170

해시의 "표준"텍스트 서식을 원하는 사람들을 위해 다음과 같은 것을 사용할 수 있습니다.

static string Hash(string input)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
        var sb = new StringBuilder(hash.Length * 2);

        foreach (byte b in hash)
        {
            // can be "x2" if you want lowercase
            sb.Append(b.ToString("X2"));
        }

        return sb.ToString();
    }
}

이것은와 같은 해시를 생성합니다 0C2E99D0949684278C30B9369B82638E1CEAD415.

또는 코드 골프 버전의 경우 :

static string Hash(string input)
{
    var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
    return string.Concat(hash.Select(b => b.ToString("x2")));
}

Disposable로 표시되어 있기 때문에이 솔루션이 SHA1Managed 개체를 처리하지 않는다는 점이 저를 괴롭 힙니다. 이 게시물은 최적화 할 때 유용 할 수 있습니다. stackoverflow.com/a/624379/991863
sky-dev

@ sky-dev, 나는 일반적으로 동의 IDisposable하지만 참조 소스 빠른 여행 은 흥미로운 일이 발생하지 않음을 보여줍니다.Dispose()
Mitch

예, Dispose 구현도 살펴 보았습니다. GarbageCollection 속도가 약간 빨라질 것입니다. 그것은 아마도 웅장한 계획에서 큰 문제가 아닐 것입니다.
sky-dev

21
@Mitch IDisposable 인터페이스를 구현하면 참조 소스에서 일어나는 일이 중요하지 않습니다. 어떤 이유로 든 .Dispose () 호출이 중요해 지도록 변경하면 이전에 작동했던 코드가 이제 문제를 일으 킵니다. 제거 할 수있는 것을 결정하기 위해 프레임 워크의 장을 들여다 보는 것은 유지 관리의 악몽으로가는 길입니다. 문서를 따르고 일회용 물건을 올바르게 취급하는 것이 좋습니다. 장기적으로 고통을 덜어 줄 것입니다.
unenthusiasticuser

2
@ijt, X2는 바이트 당 두 개의 16 진수를 사용하도록 지시합니다. x2소문자, X2대문자
Mitch

38
public string Hash(byte [] temp)
{
    using (SHA1Managed sha1 = new SHA1Managed())
    {
        var hash = sha1.ComputeHash(temp);
        return Convert.ToBase64String(hash);
    }
}

편집하다:

다음과 같이 바이트 배열을 문자열로 변환 할 때 인코딩을 지정할 수도 있습니다.

return System.Text.Encoding.UTF8.GetString(hash);

또는

return System.Text.Encoding.Unicode.GetString(hash);

나는 전에이 코드를 썼지 만 작동하지 않았다 나는 이유를 모른다
Merve Kaya 2013

1
16 진 문자열을 원하면 Base64가 잘못된 선택 일 것입니다.
Joey

@Joey는 : GrantThomas에 의해 주어진 답에 대하여, 회원은 문자열을 반환해야한다는 것을 표시
존 Gathogo

@MerveKaya : 아마도 "작동하지 않았다"는 의미를 설명해야합니다. 들어오는 바이트 배열은 무엇을 나타 냅니까? "SHA1Managed"를 어떻게 결정 했 0d71ee4472658cd5874c5578410a9d8611fc9aef습니까? 들어오는 바이트 배열을 해싱 하면 출력으로 제공해야 합니까?
존 Gathogo

Byte [] 해시는 단위 테스트에서 비롯됩니다. 질문에서 그들은 예상 해시가 0d71ee4472658cd5874c5578410a9d8611fc9aef라고 썼습니다. 단위 테스트에서 나온 것입니다
Merve Kaya

15

이것이 제가 함께했던 것입니다. 최적화를 원하는 분들은 https://stackoverflow.com/a/624379/991863을 확인 하세요 .

    public static string Hash(string stringToHash)
    {
        using (var sha1 = new SHA1Managed())
        {
            return BitConverter.ToString(sha1.ComputeHash(Encoding.UTF8.GetBytes(stringToHash)));
        }
    }

BitConverter에 의해 도입 된 대시를 원하지 않았기 때문에 BitConverter.ToString (sha1.ComputeHash (bytes)). Replace ( "-", "")를 사용해야했습니다. 그 후 그것은 매력처럼 작동했습니다! 감사!
Sam

9

가장 빠른 방법은 다음과 같습니다.

    public static string GetHash(string input)
    {
        return string.Join("", (new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input))).Select(x => x.ToString("X2")).ToArray());
    }

작은 문자 출력 사용을 위해 x2의의의 대체X2


4
SHA1Managed는 IDisposable을 구현하므로 리소스를 확보하기 위해 완료되면이를 폐기 할 수 있습니다.
rickythefox 2017 년

8

다음을 사용하여 "지정된 바이트 배열의 값을 계산"할 수 있습니다 ComputeHash.

var hash = sha1.ComputeHash(temp);

결과를 문자열 표현으로 분석하려면 {0:X2}형식 지정자를 사용하여 바이트를 형식화해야 합니다.


4

나는 여기에 내 모자를 던질 것이다.

(이 스 니펫은 두 개의 확장이므로 정적 클래스의 일부로)

//hex encoding of the hash, in uppercase.
public static string Sha1Hash (this string str)
{
    byte[] data = UTF8Encoding.UTF8.GetBytes (str);
    data = data.Sha1Hash ();
    return BitConverter.ToString (data).Replace ("-", "");
}
// Do the actual hashing
public static byte[] Sha1Hash (this byte[] data)
{
    using (SHA1Managed sha1 = new SHA1Managed ()) {
    return sha1.ComputeHash (data);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.