---
id: 5eb3e4c3a894c333d2811a3f
title: SHA-256
challengeType: 1
forumTopicId: 385328
dashedName: sha-256
---

# --description--

`SHA-2` ファミリーは `SHA-1` の替わりとなる、より強力な選択肢です。 主な違いは、ハッシュの長さです。 つまり `SHA-1` が提供するコードは、一意の組み合わせの候補が少ないより短いコードです。 `SHA-2` あるいは `SHA-256` はより長いために、より複雑なハッシュを生成し、組み合わせの可能性はより高くなっています。

# --instructions--

Research implementation details and write a function that takes a string as the parameter and returns a hash using `SHA-256`

# --hints--

`SHA256` は関数とします。

```js
assert(typeof SHA256 === 'function');
```

`SHA256("Rosetta code")` は文字列を返す必要があります。

```js
assert(typeof SHA256('Rosetta code') === 'string');
```

`SHA256("Rosetta code")` は `"764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf"` を返す必要があります。

```js
assert.equal(
  SHA256('Rosetta code'),
  '764faf5c61ac315f1497f9dfa542713965b785e5cc2f707d6468d7d1124cdfcf'
);
```

`SHA256("SHA-256 Hash")` は `"bee8c0cabdcf8c7835f40217dd35a8b0dba9134520e633f1c57285f35ca7ee3e"` を返す必要があります。

```js
assert.equal(
  SHA256('SHA-256 Hash'),
  'bee8c0cabdcf8c7835f40217dd35a8b0dba9134520e633f1c57285f35ca7ee3e'
);
```

`SHA256("implementation")` は `"da31012c40330e7e21538e7dd57503b16e8a0839159e96137090cccc9910b171"` を返す必要があります。

```js
assert.equal(
  SHA256('implementation'),
  'da31012c40330e7e21538e7dd57503b16e8a0839159e96137090cccc9910b171'
);
```

`SHA256("algorithm")` は `"b1eb2ec8ac9f31ff7918231e67f96e6deda83a9ff33ed2c67443f1df81e5ed14"` を返す必要があります。

```js
assert.equal(
  SHA256('algorithm'),
  'b1eb2ec8ac9f31ff7918231e67f96e6deda83a9ff33ed2c67443f1df81e5ed14'
);
```

`SHA256("language")` は `"a4ef304ba42a200bafd78b046e0869af9183f6eee5524aead5dcb3a5ab5f8f3f"` を返す必要があります。

```js
assert.equal(
  SHA256('language'),
  'a4ef304ba42a200bafd78b046e0869af9183f6eee5524aead5dcb3a5ab5f8f3f'
);
```

# --seed--

## --seed-contents--

```js
function SHA256(input) {

}
```

# --solutions--

```js
function SHA256(input) {
  var chrsz = 8;
  var hexcase = 0;

  function safe_add(x, y) {
    var lsw = (x & 0xffff) + (y & 0xffff);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xffff);
  }

  function S(X, n) {
    return (X >>> n) | (X << (32 - n));
  }

  function R(X, n) {
    return X >>> n;
  }

  function Ch(x, y, z) {
    return (x & y) ^ (~x & z);
  }

  function Maj(x, y, z) {
    return (x & y) ^ (x & z) ^ (y & z);
  }

  function Sigma0256(x) {
    return S(x, 2) ^ S(x, 13) ^ S(x, 22);
  }

  function Sigma1256(x) {
    return S(x, 6) ^ S(x, 11) ^ S(x, 25);
  }

  function Gamma0256(x) {
    return S(x, 7) ^ S(x, 18) ^ R(x, 3);
  }

  function Gamma1256(x) {
    return S(x, 17) ^ S(x, 19) ^ R(x, 10);
  }

  function Sigma0512(x) {
    return S(x, 28) ^ S(x, 34) ^ S(x, 39);
  }

  function Sigma1512(x) {
    return S(x, 14) ^ S(x, 18) ^ S(x, 41);
  }

  function Gamma0512(x) {
    return S(x, 1) ^ S(x, 8) ^ R(x, 7);
  }

  function Gamma1512(x) {
    return S(x, 19) ^ S(x, 61) ^ R(x, 6);
  }

  function core_sha256(m, l) {
    var K = new Array(
      0x428a2f98,
      0x71374491,
      0xb5c0fbcf,
      0xe9b5dba5,
      0x3956c25b,
      0x59f111f1,
      0x923f82a4,
      0xab1c5ed5,
      0xd807aa98,
      0x12835b01,
      0x243185be,
      0x550c7dc3,
      0x72be5d74,
      0x80deb1fe,
      0x9bdc06a7,
      0xc19bf174,
      0xe49b69c1,
      0xefbe4786,
      0xfc19dc6,
      0x240ca1cc,
      0x2de92c6f,
      0x4a7484aa,
      0x5cb0a9dc,
      0x76f988da,
      0x983e5152,
      0xa831c66d,
      0xb00327c8,
      0xbf597fc7,
      0xc6e00bf3,
      0xd5a79147,
      0x6ca6351,
      0x14292967,
      0x27b70a85,
      0x2e1b2138,
      0x4d2c6dfc,
      0x53380d13,
      0x650a7354,
      0x766a0abb,
      0x81c2c92e,
      0x92722c85,
      0xa2bfe8a1,
      0xa81a664b,
      0xc24b8b70,
      0xc76c51a3,
      0xd192e819,
      0xd6990624,
      0xf40e3585,
      0x106aa070,
      0x19a4c116,
      0x1e376c08,
      0x2748774c,
      0x34b0bcb5,
      0x391c0cb3,
      0x4ed8aa4a,
      0x5b9cca4f,
      0x682e6ff3,
      0x748f82ee,
      0x78a5636f,
      0x84c87814,
      0x8cc70208,
      0x90befffa,
      0xa4506ceb,
      0xbef9a3f7,
      0xc67178f2
    );
    var HASH = new Array(
      0x6a09e667,
      0xbb67ae85,
      0x3c6ef372,
      0xa54ff53a,
      0x510e527f,
      0x9b05688c,
      0x1f83d9ab,
      0x5be0cd19
    );
    var W = new Array(64);
    var a, b, c, d, e, f, g, h, i, j;
    var T1, T2;

    m[l >> 5] |= 0x80 << (24 - (l % 32));
    m[(((l + 64) >> 9) << 4) + 15] = l;

    for (var i = 0; i < m.length; i += 16) {
      a = HASH[0];
      b = HASH[1];
      c = HASH[2];
      d = HASH[3];
      e = HASH[4];
      f = HASH[5];
      g = HASH[6];
      h = HASH[7];

      for (var j = 0; j < 64; j++) {
        if (j < 16) W[j] = m[j + i];
        else
          W[j] = safe_add(
            safe_add(
              safe_add(Gamma1256(W[j - 2]), W[j - 7]),
              Gamma0256(W[j - 15])
            ),
            W[j - 16]
          );

        T1 = safe_add(
          safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]),
          W[j]
        );
        T2 = safe_add(Sigma0256(a), Maj(a, b, c));

        h = g;
        g = f;
        f = e;
        e = safe_add(d, T1);
        d = c;
        c = b;
        b = a;
        a = safe_add(T1, T2);
      }

      HASH[0] = safe_add(a, HASH[0]);
      HASH[1] = safe_add(b, HASH[1]);
      HASH[2] = safe_add(c, HASH[2]);
      HASH[3] = safe_add(d, HASH[3]);
      HASH[4] = safe_add(e, HASH[4]);
      HASH[5] = safe_add(f, HASH[5]);
      HASH[6] = safe_add(g, HASH[6]);
      HASH[7] = safe_add(h, HASH[7]);
    }
    return HASH;
  }

  function core_sha512(m, l) {
    var K = new Array(
      0x428a2f98d728ae22,
      0x7137449123ef65cd,
      0xb5c0fbcfec4d3b2f,
      0xe9b5dba58189dbbc,
      0x3956c25bf348b538,
      0x59f111f1b605d019,
      0x923f82a4af194f9b,
      0xab1c5ed5da6d8118,
      0xd807aa98a3030242,
      0x12835b0145706fbe,
      0x243185be4ee4b28c,
      0x550c7dc3d5ffb4e2,
      0x72be5d74f27b896f,
      0x80deb1fe3b1696b1,
      0x9bdc06a725c71235,
      0xc19bf174cf692694,
      0xe49b69c19ef14ad2,
      0xefbe4786384f25e3,
      0x0fc19dc68b8cd5b5,
      0x240ca1cc77ac9c65,
      0x2de92c6f592b0275,
      0x4a7484aa6ea6e483,
      0x5cb0a9dcbd41fbd4,
      0x76f988da831153b5,
      0x983e5152ee66dfab,
      0xa831c66d2db43210,
      0xb00327c898fb213f,
      0xbf597fc7beef0ee4,
      0xc6e00bf33da88fc2,
      0xd5a79147930aa725,
      0x06ca6351e003826f,
      0x142929670a0e6e70,
      0x27b70a8546d22ffc,
      0x2e1b21385c26c926,
      0x4d2c6dfc5ac42aed,
      0x53380d139d95b3df,
      0x650a73548baf63de,
      0x766a0abb3c77b2a8,
      0x81c2c92e47edaee6,
      0x92722c851482353b,
      0xa2bfe8a14cf10364,
      0xa81a664bbc423001,
      0xc24b8b70d0f89791,
      0xc76c51a30654be30,
      0xd192e819d6ef5218,
      0xd69906245565a910,
      0xf40e35855771202a,
      0x106aa07032bbd1b8,
      0x19a4c116b8d2d0c8,
      0x1e376c085141ab53,
      0x2748774cdf8eeb99,
      0x34b0bcb5e19b48a8,
      0x391c0cb3c5c95a63,
      0x4ed8aa4ae3418acb,
      0x5b9cca4f7763e373,
      0x682e6ff3d6b2b8a3,
      0x748f82ee5defb2fc,
      0x78a5636f43172f60,
      0x84c87814a1f0ab72,
      0x8cc702081a6439ec,
      0x90befffa23631e28,
      0xa4506cebde82bde9,
      0xbef9a3f7b2c67915,
      0xc67178f2e372532b,
      0xca273eceea26619c,
      0xd186b8c721c0c207,
      0xeada7dd6cde0eb1e,
      0xf57d4f7fee6ed178,
      0x06f067aa72176fba,
      0x0a637dc5a2c898a6,
      0x113f9804bef90dae,
      0x1b710b35131c471b,
      0x28db77f523047d84,
      0x32caab7b40c72493,
      0x3c9ebe0a15c9bebc,
      0x431d67c49c100d4c,
      0x4cc5d4becb3e42b6,
      0x597f299cfc657e2a,
      0x5fcb6fab3ad6faec,
      0x6c44198c4a475817
    );
    var HASH = new Array(
      0x6a09e667f3bcc908,
      0xbb67ae8584caa73b,
      0x3c6ef372fe94f82b,
      0xa54ff53a5f1d36f1,
      0x510e527fade682d1,
      0x9b05688c2b3e6c1f,
      0x1f83d9abfb41bd6b,
      0x5be0cd19137e2179
    );
    var W = new Array(80);
    var a, b, c, d, e, f, g, h, i, j;
    var T1, T2;
  }

  function str2binb(str) {
    var bin = Array();
    var mask = (1 << chrsz) - 1;
    for (var i = 0; i < str.length * chrsz; i += chrsz)
      bin[i >> 5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - (i % 32));
    return bin;
  }

  function binb2str(bin) {
    var str = '';
    var mask = (1 << chrsz) - 1;
    for (var i = 0; i < bin.length * 32; i += chrsz)
      str += String.fromCharCode((bin[i >> 5] >>> (24 - (i % 32))) & mask);
    return str;
  }

  function binb2hex(binarray) {
    var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef';
    var str = '';
    for (var i = 0; i < binarray.length * 4; i++) {
      str +=
        hex_tab.charAt((binarray[i >> 2] >> ((3 - (i % 4)) * 8 + 4)) & 0xf) +
        hex_tab.charAt((binarray[i >> 2] >> ((3 - (i % 4)) * 8)) & 0xf);
    }
    return str;
  }

  function binb2b64(binarray) {
    var tab =
      'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    var str = '';
    for (var i = 0; i < binarray.length * 4; i += 3) {
      var triplet =
        (((binarray[i >> 2] >> (8 * (3 - (i % 4)))) & 0xff) << 16) |
        (((binarray[(i + 1) >> 2] >> (8 * (3 - ((i + 1) % 4)))) & 0xff) << 8) |
        ((binarray[(i + 2) >> 2] >> (8 * (3 - ((i + 2) % 4)))) & 0xff);
      for (var j = 0; j < 4; j++) {
        if (i * 8 + j * 6 > binarray.length * 32) str += '';
        else str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f);
      }
    }
    return str;
  }

  function hex_sha2(s) {
    return binb2hex(core_sha256(str2binb(s), s.length * chrsz));
  }

  function b64_sha2(s) {
    return binb2b64(core_sha256(str2binb(s), s.length * chrsz));
  }

  function str_sha2(s) {
    return binb2str(core_sha256(str2binb(s), s.length * chrsz));
  }
  return hex_sha2(input);
}
```
