Osy#betaRun it on Osyrin: osyrin.com

Reference / Types

byte[]

byte[] Magic = new byte[] { 0x89, 0x50, 0x4E, 0x47 };

Raw bytes — a file's contents, a digest, a key. Write one as C# does, `new byte[] { 0x89, 0x50 }`, or as a collection expression `[0x89, 0x50]` wherever a `byte[]` is expected. Each element is an integer constant from 0 to 255, converted exactly as C# converts it.

stable2 examples compiled by CItypesbytesauthoring

Summary#

A byte[] is raw bytes: what File.ReadAllBytes hands back, what Crypto.Sha256 answers, what an entity's byte[] member stores. When you know the bytes up front — a file signature, a fixed prefix, a test fixture — write them down the way you would in C#.

Signature#

byte[] a = new byte[] { 0x89, 0x50, 0x4E, 0x47 };   // the explicit array creation
byte[] b = [0x89, 0x50, 0x4E, 0x47];                // a collection expression, target-typed to byte[]
byte[] zeros = new byte[16];                        // sixteen zero bytes — the length must be a constant
File.WriteAllBytes("sig.bin", [1, 2, 3]);           // an argument is a target too

Description#

It is one value, not a list#

In Osy# a byte[] is a single value — the same one Convert.FromBase64String or Text.ToBytes produces — and not a collection of numbers. So everything that takes bytes takes a literal: the file store, Convert.ToBase64String, the Crypto family, Http.Put, and an entity's byte[] member. There is no index write; bytes you compute come from the functions that produce them rather than from filling in a buffer.

Where [ … ] becomes bytes#

new byte[] { … } is a byte[] anywhere, because you named the element type. A bare [1, 2, 3] is a byte[] only where one is expected — a byte[] local, return, parameter or member, or an argument whose parameter takes bytes. Anywhere else it is an int[], as it would be in C#:

byte[] b = [1, 2];     // bytes: the declaration asks for them
var n = [1, 2];        // an int[]: nothing asked

What each element may be#

Each element is converted the way C# converts a constant int to a byte, and refused where C# refuses it:

elementanswer
a constant from 0 to 255 — 7, 0xFF, 255that byte
a constant outside that range — 256, -1an error: constant value '256' cannot be converted to a 'byte'
a computed int — a variable, a parameteran error: the elements must be constants
anything that is not an integeran error naming its type

Bytes built from values you have at run time come from Text.ToBytes(s), Encoding.UTF8.GetBytes(s) (or any other encoding, code pages included — see Encoding — Base64, hex, text encodings, URL, HTML), Convert.FromBase64String(s), Convert.FromHexString(hex) or Crypto.FromHex(hex) — see Signing with raw bytes — Crypto.HmacSha256, Sha256, ToHex, and Text.ToBytes.

Reading part of one#

A byte[] is sliced the way C# slices one — file.Take(8) (the first eight bytes), file.Skip(8) (all but the first eight), file.Slice(4, 2) (two bytes from index 4, Span's spelling) — and file.Length is its size. Each answers a new byte[]; the original is never changed.

Examples#

bool LooksLikePng(byte[] file) {
  byte[] png = new byte[] { 0x89, 0x50, 0x4E, 0x47 };
  return Crypto.ToHex(file).StartsWith(Crypto.ToHex(png));
}
string Encoded() => Convert.ToBase64String([0x01, 0x02, 0xFF]);

See also#

Related

Signing with raw bytes — Crypto.HmacSha256, Sha256, ToHex, and Text.ToBytes

The byte-in, byte-out half of the crypto surface. Real request-signing schemes chain their HMACs — each step's raw…

Constant expressions

Some places take a value that must be known at compile time — an attribute argument, a config setting, a workflow…

Every type, in one list

The complete vocabulary of built-in types — the scalars you can store, the collections, the two callable spellings…