Hash the exact bytes the application intends to identify
SHA-256 maps a byte sequence to a fixed-size digest. It does not decide which encoding produced those bytes, which record fields are significant, or whether a sender should be trusted. The lesson first creates the UTF-8 bytes for abc, then calls the real SHA256.HashData API and prints a hexadecimal representation of the result. There is no public request, password database or native interop. This narrow experiment establishes a reproducible byte fingerprint and supplies a familiar test vector against which an implementation can be checked. A digest's usefulness depends on the surrounding comparison and trust contract.
Interpret the known digest and the changed-input comparison
UTF-8 represents the three ASCII characters as bytes 61 62 63. Hashing that exact sequence produces the 32-byte SHA-256 digest printed as 64 uppercase hexadecimal characters: the line begins BA7816BF and ends F20015AD. The program separately hashes abd and compares the resulting digest bytes with the first digest. They are different, so the second line is False. The visible uppercase spelling comes from Convert.ToHexString; letter case in a textual hex display does not change the underlying digest bytes. The comparison is about these two concrete inputs, not a proof that different inputs can never collide.
Integrity and sender authentication require different evidence
If a consumer receives content and a checksum through the same untrusted channel, an attacker who can replace both can recompute a consistent checksum. A digest can detect accidental differences or compare against a trusted expected value, but that trust must come from somewhere outside the untrusted pair. HMAC introduces a shared secret into a message-authentication design; signatures use a different key and verification model. Choosing and managing those mechanisms requires their own protocol decisions. This sample deliberately performs neither authentication operation and should not label its output as proof of an authorized sender or an untampered network session.
A fast digest is not a password-storage construction
A general-purpose cryptographic digest is designed for efficient computation over bytes. Password verification has different requirements, including an appropriate password-hashing construction, per-password salts and a work factor chosen for the system. Hashing a password once with SHA-256 does not provide those properties merely because the algorithm is cryptographic. Likewise, the digest is not encryption and cannot be decrypted to recover the original content. This lesson's tiny hard-coded strings are test inputs for an integrity primitive. Do not transplant the code into credential storage or describe hex output as a protected version of a secret.
Verify algorithm support for the actual target
Cryptography support is platform dependent, so an API available to a desktop project is not automatically available in a browser runtime. Microsoft's cross-platform guidance specifically lists managed SHA-2 support in browser WebAssembly, including SHA-256, while other algorithms have different tables. The lesson uses only the supported operation it actually demonstrates rather than inferring support for every class in the namespace. Its expected output is independent of machine culture because the byte input and hexadecimal conversion are explicit. When adding another algorithm or keyed operation, check that exact target and API instead of extrapolating from this successful hash.
Make byte identity visible before comparing digests
First change the source text to `abc ` and print its UTF-8 hexadecimal bytes before hashing. Explain why a trailing newline is data and why its digest should not be compared with the original three-byte test vector. For the second exercise, obtain a digest from the same original bytes twice, once from a cloned array, and compare the digest arrays by content. Contrast that result with comparing two array references directly. These exercises isolate two frequent mistakes: unacknowledged differences in the hashed byte sequence and treating array identity as a comparison of the values it contains.
- Hint for the newline: the bytes become 6162630A, so the original known digest no longer describes the input.
- Hint for a clone: identical bytes produce identical digest contents; two separately allocated arrays need a content comparison.
Put the digest into a clearly bounded protocol
Before using a digest in an importer, state what exact bytes are hashed, where the expected digest comes from and what a mismatch causes. If text is normalized or reserialized first, that transformation becomes part of the contract and may discard distinctions in the original representation. If a secret-dependent authentication check is required, choose the appropriate authentication API and comparison guidance rather than extending this simple example casually. The original two-line output supports a precise claim: the framework produced the known SHA-256 fingerprint for three specified bytes and a different fingerprint for a specific changed input.
- Hash a defined byte sequence, including intentional newline and encoding choices.
- Distinguish content integrity, authentication, encryption and password verification.
- Check the exact algorithm on the runtime that will execute it.
A working example
using System;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.IO;
using System.IO.Compression;
using System.Buffers.Binary;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Threading;
using System.Threading.Tasks;
byte[] digest = SHA256.HashData(Encoding.UTF8.GetBytes("abc"));
Console.WriteLine(Convert.ToHexString(digest));
Console.WriteLine(digest.SequenceEqual(SHA256.HashData(Encoding.UTF8.GetBytes("abd"))));
Expected output
BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD False
A digest depends on exact bytes and does not by itself authenticate the sender or safely store a password.