본문으로 건너뛰기
토파즈6.0 · 출시 전
다운로드 →

문서 검색

명세 6.0

방향키로 결과를 고르고 Enter를 눌러 여세요.

API 이름, 진단 번호, 규칙 또는 프로젝트 주제를 입력하세요.

    라이브러리

    std.bytes

    Construct byte sequences and use byte buffers, encodings, hashes, and compression.

    이 모듈의 API

    33개 API

    이름모듈
    ByteBuffer.allocate →std.bytes →
    ByteBuffer.copy →std.bytes →
    ByteBuffer.fill →std.bytes →
    ByteBuffer.fromBytes →std.bytes →
    ByteBuffer.get →std.bytes →
    ByteBuffer.length →std.bytes →
    ByteBuffer.set →std.bytes →
    ByteBuffer.toBytes →std.bytes →
    Bytes.concat →std.bytes →
    Bytes.crc32 →std.bytes →
    Bytes.decodeUtf8 →std.bytes →
    Bytes.deflateCompress →std.bytes →
    Bytes.deflateDecompress →std.bytes →
    Bytes.deflateFixedCompress →std.bytes →
    Bytes.empty →std.bytes →
    Bytes.fromArray →std.bytes →
    Bytes.fromBase64 →std.bytes →
    Bytes.fromHex →std.bytes →
    Bytes.get →std.bytes →
    Bytes.gzipCompress →std.bytes →
    Bytes.gzipDecompress →std.bytes →
    Bytes.hmacSha256 →std.bytes →
    Bytes.length →std.bytes →
    Bytes.reedSolomon255223Protect →std.bytes →
    Bytes.sha256 →std.bytes →
    Bytes.sha512 →std.bytes →
    Bytes.slice →std.bytes →
    Bytes.toArray →std.bytes →
    Bytes.toBase64 →std.bytes →
    Bytes.toHex →std.bytes →
    Bytes.zlibFixedCompress →std.bytes →
    Bytes.zstdCompress →std.bytes →
    Bytes.zstdDecompress →std.bytes →

    Module

    링크

    Bytes stores immutable octets. ByteBuffer is a mutable value with a fixed length. Indexing counts bytes and text conversion uses an explicit encoding.

    Why

    링크

    Binary data needs exact byte values, explicit text encodings, and a mutable buffer for incremental work.

    Availability

    링크

    Import std.bytes in language mode 5.21. The current compiler selects std/bytes.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.

    Exported types

    링크

    export type Bytes = Bytes

    export type ByteBuffer = ByteBuffer

    Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.

    Public API

    링크

    ByteBuffer.allocate →

    ByteBuffer.copy →

    ByteBuffer.fill →

    ByteBuffer.fromBytes →

    ByteBuffer.get →

    ByteBuffer.length →

    ByteBuffer.set →

    ByteBuffer.toBytes →

    Bytes.concat →

    Bytes.crc32 →

    Bytes.decodeUtf8 →

    Bytes.deflateCompress →

    Bytes.deflateDecompress →

    Bytes.deflateFixedCompress →

    Bytes.empty →

    Bytes.fromArray →

    Bytes.fromBase64 →

    Bytes.fromHex →

    Bytes.get →

    Bytes.gzipCompress →

    Bytes.gzipDecompress →

    Bytes.hmacSha256 →

    Bytes.length →

    Bytes.reedSolomon255223Protect →

    Bytes.sha256 →

    Bytes.sha512 →

    Bytes.slice →

    Bytes.toArray →

    Bytes.toBase64 →

    Bytes.toHex →

    Bytes.zlibFixedCompress →

    Bytes.zstdCompress →

    Bytes.zstdDecompress →

    Pending contracts

    링크

    Read collection sizes, keys, and values as properties

    링크
    규칙topaz.stdlib.contract.collection-properties.rule

    Read collection sizes, keys, and values as properties

    Bytes.length and ByteBuffer.length are read-only int properties that report the number of bytes.

    JSONValue.length is an Option<int> property. Arrays and objects return Some(count) for their element or member count. Other JSON kinds return None().

    JSONValue.keys and JSONValue.values are properties returning Option<Array<string>> and Option<Array<JSONValue>>. Objects return Some(keys) or Some(values). Other JSON kinds return None().

    Read these properties without parentheses, as with Array.length, Map.length, Map.keys, Map.values, and Set.length. Calling a property value is rejected as a non-callable value.

    이유

    The same collection observation should use the same syntax across core collections and library values. Keeping JSONValue results optional preserves its distinction between collections and scalar values.

    Read the same properties on core collections

    링크
    main.tpzRead the same properties on core collections플레이그라운드 열기 →
    1. import std.io
    2. let array = [2, 3]
    3. let entries = map { "name": "Topaz" }
    4. let values = set { 2, 3 }
    5. io.writeLine("{array.length}:{entries.length}:{values.length}")
    6. io.writeLine(entries.keys[0])
    7. io.writeLine(entries.values[0])
    기대 출력종료 코드 0
    2:1:2
    name
    Topaz
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 2:1:2
    2. name
    3. Topaz

    Read a byte sequence size

    링크
    main.tpzRead a byte sequence size플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. let bytes = Bytes.empty()
    4. let size: int = bytes.length
    5. io.writeLine("{size}")
    기대 출력종료 코드 0
    0
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 0

    Read a byte buffer size

    링크
    main.tpzRead a byte buffer size플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let buffer = ByteBuffer.allocate(3)
    4. let size: int = buffer.length
    5. io.writeLine("{size}")
    기대 출력종료 코드 0
    3
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 3

    Read JSON sizes and preserve optional results

    링크
    main.tpzRead JSON sizes and preserve optional results플레이그라운드 열기 →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let array = test.assertOk(json.parse("[1,2]"))
    5. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let arraySize: Option<int> = array.length
    8. let objectSize: Option<int> = object.length
    9. let scalarSize: Option<int> = scalar.length
    10. test.assertEq(test.assertSome(arraySize), 2)
    11. test.assertEq(test.assertSome(objectSize), 1)
    12. test.assertNone(scalarSize)
    13. io.writeLine("JSON sizes read")
    기대 출력종료 코드 0
    JSON sizes read
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. JSON sizes read

    Read JSON object keys

    링크
    main.tpzRead JSON object keys플레이그라운드 열기 →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    5. let array = test.assertOk(json.parse("[]"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let names: Option<Array<string>> = object.keys
    8. test.assertEq(test.assertSome(names)[0], "name")
    9. test.assertNone(array.keys)
    10. test.assertNone(scalar.keys)
    11. io.writeLine("JSON keys read")
    기대 출력종료 코드 0
    JSON keys read
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. JSON keys read

    Read JSON object values

    링크
    main.tpzRead JSON object values플레이그라운드 열기 →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    5. let array = test.assertOk(json.parse("[]"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let values = test.assertSome(object.values)
    8. test.assertEq(test.assertSome(values[0].asString()), "Topaz")
    9. test.assertNone(array.values)
    10. test.assertNone(scalar.values)
    11. io.writeLine("JSON values read")
    기대 출력종료 코드 0
    JSON values read
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. JSON values read

    Reject calling Bytes.length

    링크
    main.tpzReject calling Bytes.length플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. function inspect(value: Bytes) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling ByteBuffer.length

    링크
    main.tpzReject calling ByteBuffer.length플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. function inspect(value: ByteBuffer) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.length

    링크
    main.tpzReject calling JSONValue.length플레이그라운드 열기 →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.keys

    링크
    main.tpzReject calling JSONValue.keys플레이그라운드 열기 →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.keys()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.values

    링크
    main.tpzReject calling JSONValue.values플레이그라운드 열기 →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.values()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Diagnostics

    링크

    Value is not callable →

    Test collection emptiness with length

    링크
    규칙topaz.stdlib.contract.collection-emptiness.rule

    Test collection emptiness with length

    Test whether a Bytes, Map, or Set value is empty by comparing its length property with zero. The comparison is true exactly when the collection has no bytes, entries, or elements.

    Bytes, Map, and Set do not expose an isEmpty member. Read the length property and use the ordinary equality operator.

    이유

    A collection already exposes its count through length. Comparing that value with zero expresses emptiness for every collection without another query name or a type-specific method.

    Test empty and nonempty maps with length

    링크
    main.tpzTest empty and nonempty maps with length플레이그라운드 열기 →
    1. import std.io
    2. let empty: Map<string, int> = map {}
    3. let filled = map { "one": 1 }
    4. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    기대 출력종료 코드 0
    true:false
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true:false

    Test empty and nonempty sets with length

    링크
    main.tpzTest empty and nonempty sets with length플레이그라운드 열기 →
    1. import std.io
    2. let empty: Set<int> = set {}
    3. let filled = set { 1 }
    4. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    기대 출력종료 코드 0
    true:false
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true:false

    Test empty and nonempty byte sequences with length

    링크
    main.tpzTest empty and nonempty byte sequences with length플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.test
    3. import std.io
    4. let empty = Bytes.empty()
    5. let filled = test.assertOk(Bytes.fromArray([1]))
    6. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    기대 출력종료 코드 0
    true:false
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. true:false

    Reject Bytes.isEmpty

    링크
    main.tpzReject Bytes.isEmpty플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. function inspect(value: Bytes) -> () {
    3. let result = value.isEmpty()
    4. return ()
    5. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Reject Map.isEmpty

    링크
    main.tpzReject Map.isEmpty플레이그라운드 열기 →
    1. function inspect(value: Map<string, int>) -> () {
    2. let result = value.isEmpty()
    3. return ()
    4. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Reject Set.isEmpty

    링크
    main.tpzReject Set.isEmpty플레이그라운드 열기 →
    1. function inspect(value: Set<int>) -> () {
    2. let result = value.isEmpty()
    3. return ()
    4. }
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz check main.tpz --format json · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 check. 종료 코드가 0이 아닙니다.

    Diagnostics

    링크

    Unknown member or field →

    Construct and inspect immutable byte sequences

    링크
    규칙topaz.stdlib.contract.bytes-values.rule

    Construct and inspect immutable byte sequences

    A Bytes value is an immutable ordered sequence of octets. Each octet is an int from 0 through 255.

    Bytes.empty returns the empty sequence. Bytes.fromArray accepts an Array<int> and returns an independent snapshot in Ok.

    Bytes.fromArray returns Err with a string identifying the first element outside 0 through 255. It does not wrap, clamp, or return a partial sequence.

    Bytes.toArray returns a new Array<int> in byte order. Mutating that array or the original input array does not change an existing Bytes value.

    Bytes.concat returns the receiver bytes followed by the argument bytes. Either input may be empty and both inputs retain their contents.

    Bytes.get uses a zero-based byte index. It returns Some(byte) within the sequence and None() for every negative or past-end index.

    Bytes.length is the number of bytes and is read as a property. Compare it with zero to test emptiness.

    Receivers and supplied arguments evaluate once from left to right before the operation begins. These operations perform no I/O or text normalization.

    A correctly typed lookup or concatenation has no data-dependent Result failure. Allocation exhaustion is an operational failure and is not a decoded data error.

    이유

    Exact octets keep binary payloads independent of text encoding. Snapshot conversion prevents later array edits from silently changing a payload.

    Preserve empty values and byte order

    링크
    main.tpzPreserve empty values and byte order플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let empty = test.assertOk(Bytes.fromArray([]))
    5. let value = test.assertOk(Bytes.fromArray([0, 128, 255]))
    6. io.writeLine(Bytes.empty().toHex())
    7. io.writeLine(empty.concat(value).toHex())
    8. io.writeLine(value.concat(test.assertOk(Bytes.fromArray([1]))).toHex())
    기대 출력종료 코드 0
    
    0080ff
    0080ff01
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 0080ff
    2. 0080ff01

    Reject out-of-range array elements

    링크
    main.tpzReject out-of-range array elements플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for values in ([[0, -1, 255], [0, 256, 255]]) {
    4. match (Bytes.fromArray(values)) {
    5. case Err(_) => io.writeLine("invalid byte")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    기대 출력종료 코드 0
    invalid byte
    invalid byte
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid byte
    2. invalid byte

    Read optional bytes at both boundaries

    링크
    main.tpzRead optional bytes at both boundaries플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let value = test.assertOk(Bytes.fromArray([0, 128, 255]))
    5. for index in ([-1, 0, 2, 3]) {
    6. match (value.get(index)) {
    7. case Some(byte) => io.writeLine("{byte}")
    8. case None() => io.writeLine("absent")
    9. }
    10. }
    기대 출력종료 코드 0
    absent
    0
    255
    absent
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. absent
    2. 0
    3. 255
    4. absent

    Keep array edits independent from bytes

    링크
    main.tpzKeep array edits independent from bytes플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let mut input = [0, 255]
    5. let value = test.assertOk(Bytes.fromArray(input))
    6. let mut output = value.toArray()
    7. input[0] = 7
    8. output[1] = 8
    9. io.writeLine(value.toHex())
    10. io.writeLine("{input[0]},{output[1]}")
    기대 출력종료 코드 0
    00ff
    7,8
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 00ff
    2. 7,8

    Evaluate the receiver before its argument

    링크
    main.tpzEvaluate the receiver before its argument플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. function receiver() -> Bytes {
    4. io.writeLine("receiver")
    5. return "a".encodeUtf8()
    6. }
    7. function argument() -> Bytes {
    8. io.writeLine("argument")
    9. return "b".encodeUtf8()
    10. }
    11. io.writeLine(receiver().concat(argument()).toHex())
    기대 출력종료 코드 0
    receiver
    argument
    6162
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. receiver
    2. argument
    3. 6162

    Select explicit byte intervals

    링크
    규칙topaz.stdlib.contract.bytes-slice.rule

    Select explicit byte intervals

    Bytes.slice uses a start position and an exclusive end position measured in bytes.

    Valid bounds satisfy 0 <= start <= end <= length. The result contains exactly the bytes from start through end minus one.

    Equal endpoints produce empty Bytes, including endpoints at zero and at length. A full interval preserves every byte.

    Negative bounds, inverted bounds, and endpoints beyond length produce TPZ4001 at runtime. Bounds are not clamped or interpreted from the end.

    Slicing never changes the receiver. The receiver, start, and end expressions evaluate once in that order before the bounds are checked.

    A byte interval may split a UTF-8 encoding. Bytes.slice preserves those selected octets and Bytes.decodeUtf8 reports invalid text when they form an incomplete sequence.

    이유

    An explicit interval should identify exactly the requested payload. Rejecting an invalid interval makes a mistaken byte count visible before subsequent decoding.

    Select empty and nonempty intervals

    링크
    main.tpzSelect empty and nonempty intervals플레이그라운드 열기 →
    1. import std.io
    2. let value = "abcd".encodeUtf8()
    3. io.writeLine(value.slice(0, 0).toHex())
    4. io.writeLine(value.slice(1, 3).toHex())
    5. io.writeLine(value.slice(4, 4).toHex())
    6. io.writeLine(value.toHex())
    기대 출력종료 코드 0
    
    6263
    
    61626364
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 6263
    2. 61626364

    Keep byte slicing separate from UTF-8 validation

    링크
    main.tpzKeep byte slicing separate from UTF-8 validation플레이그라운드 열기 →
    1. import std.io
    2. let byte = "é".encodeUtf8().slice(0, 1)
    3. io.writeLine(byte.toHex())
    4. match (byte.decodeUtf8()) {
    5. case Err(_) => io.writeLine("invalid UTF-8")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    기대 출력종료 코드 0
    c3
    invalid UTF-8
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. c3
    2. invalid UTF-8

    Reject a negative slice start

    링크
    main.tpzReject a negative slice start플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(-1, 2)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject an inverted byte interval

    링크
    main.tpzReject an inverted byte interval플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(3, 2)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject an endpoint beyond the sequence

    링크
    main.tpzReject an endpoint beyond the sequence플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(0, 5)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Diagnostics

    링크

    Index out of bounds →

    Use a canonical hexadecimal spelling

    링크
    규칙topaz.stdlib.contract.bytes-hex.rule

    Use a canonical hexadecimal spelling

    Bytes.toHex emits two lowercase ASCII hexadecimal digits per byte with the high nibble first. Empty Bytes produces an empty string.

    Bytes.fromHex accepts an even number of digits drawn from 0 through 9 and a through f. Empty text returns Ok with empty Bytes.

    Uppercase letters, prefixes, separators, whitespace, non-ASCII characters, and an odd digit count return Err with a string describing invalid hex input.

    Decoding returns the entire byte sequence in Ok or an error with no decoded prefix. It never mutates an input value.

    Encoding then decoding recovers the bytes exactly. Decoding then encoding preserves every accepted input spelling.

    The input expression evaluates once. These conversions perform no I/O and do not apply Unicode normalization.

    이유

    One accepted hexadecimal spelling makes serialized byte text stable for comparison and reproduction. Data that uses another spelling can be normalized explicitly before decoding.

    Decode byte pairs and emit lowercase text

    링크
    main.tpzDecode byte pairs and emit lowercase text플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. io.writeLine(test.assertOk(Bytes.fromHex("")).toHex())
    5. io.writeLine(test.assertOk(Bytes.fromHex("000f80ff")).toHex())
    기대 출력종료 코드 0
    
    000f80ff
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 000f80ff

    Reject malformed hexadecimal strings

    링크
    main.tpzReject malformed hexadecimal strings플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for text in (["0", "gg", "0x00", "00 11", "00"]) {
    4. match (Bytes.fromHex(text)) {
    5. case Err(_) => io.writeLine("invalid hex")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    기대 출력종료 코드 0
    invalid hex
    invalid hex
    invalid hex
    invalid hex
    invalid hex
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid hex
    2. invalid hex
    3. invalid hex
    4. invalid hex
    5. invalid hex

    Reject uppercase hexadecimal input

    링크
    main.tpzReject uppercase hexadecimal input플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. match (Bytes.fromHex("CAfe")) {
    4. case Err(_) => io.writeLine("uppercase rejected")
    5. case Ok(_) => io.writeLine("accepted")
    6. }
    기대 출력종료 코드 0
    uppercase rejected
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. uppercase rejected

    Encode and validate padded Base64

    링크
    규칙topaz.stdlib.contract.bytes-base64.rule

    Encode and validate padded Base64

    Bytes.toBase64 uses the RFC 4648 standard alphabet with plus and slash. Its output has no whitespace or line wrapping.

    A final group containing one byte ends with two equals signs. A final group containing two bytes ends with one equals sign.

    Bytes.fromBase64 accepts complete groups of four characters. Padding appears at the end of the final group and all unused bits are zero.

    Missing or misplaced padding, nonzero unused bits, whitespace, non-ASCII characters, minus signs, and underscores return Err with a string.

    Empty bytes encode as empty text and empty text decodes to Ok with empty Bytes. Invalid text never returns a partial byte sequence.

    The input is evaluated once and is unchanged. Encoding then decoding recovers the input bytes exactly without any external effects.

    이유

    A precise alphabet and padding rule let independent implementations exchange the same bytes. Rejecting nonzero unused bits prevents several texts from representing one accepted encoding.

    Use standard Base64 vectors

    링크
    main.tpzUse standard Base64 vectors플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for text in (["", "f", "fo", "foo"]) {
    5. io.writeLine(text.encodeUtf8().toBase64())
    6. }
    7. for text in (["", "Zg==", "Zm8=", "Zm9v"]) {
    8. io.writeLine(test.assertOk(Bytes.fromBase64(text)).toHex())
    9. }
    기대 출력종료 코드 0
    
    Zg==
    Zm8=
    Zm9v
    
    66
    666f
    666f6f
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. Zg==
    2. Zm8=
    3. Zm9v
    4. 66
    5. 666f
    6. 666f6f

    Reject padding and alphabet errors

    링크
    main.tpzReject padding and alphabet errors플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for text in (["Zg", "Zh==", "Zg== ", "_w==", "Zg==Zg==", "=g=="]) {
    4. match (Bytes.fromBase64(text)) {
    5. case Err(_) => io.writeLine("invalid Base64")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    기대 출력종료 코드 0
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid Base64
    2. invalid Base64
    3. invalid Base64
    4. invalid Base64
    5. invalid Base64
    6. invalid Base64

    Decode UTF-8 without replacing data

    링크
    규칙topaz.stdlib.contract.bytes-utf8.rule

    Decode UTF-8 without replacing data

    Bytes.decodeUtf8 returns Ok with the exact Unicode scalar sequence encoded by valid UTF-8 bytes.

    Empty Bytes returns Ok with an empty string. A leading UTF-8 encoding of U+FEFF remains in the returned string.

    Overlong encodings, isolated continuation bytes, incomplete sequences, surrogate encodings, and values above U+10FFFF return Err with a string.

    Decoding does not insert replacement characters, normalize scalars, alter newline sequences, or discard a byte order mark.

    For a string, encodeUtf8 followed by decodeUtf8 returns the original string. Re-encoding any successfully decoded sequence recovers its original bytes.

    The receiver evaluates once and remains unchanged. No text is exposed before the entire sequence has passed validation.

    이유

    Lossless decoding keeps malformed input visible and preserves distinctions needed by file formats, checksums, and text layout.

    Retain a byte order mark and combining sequence

    링크
    main.tpzRetain a byte order mark and combining sequence플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "efbbbf", "65cc81", "0d0a", "f09f9880"]) {
    5. let decoded = test.assertOk(test.assertOk(Bytes.fromHex(hex)).decodeUtf8())
    6. io.writeLine(decoded.encodeUtf8().toHex())
    7. }
    기대 출력종료 코드 0
    
    efbbbf
    65cc81
    0d0a
    f09f9880
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. efbbbf
    2. 65cc81
    3. 0d0a
    4. f09f9880

    Reject malformed UTF-8 categories

    링크
    main.tpzReject malformed UTF-8 categories플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["80", "c080", "e282", "eda080", "f4908080"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).decodeUtf8()) {
    6. case Err(_) => io.writeLine("invalid UTF-8")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    기대 출력종료 코드 0
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid UTF-8
    2. invalid UTF-8
    3. invalid UTF-8
    4. invalid UTF-8
    5. invalid UTF-8

    Allocate buffers and convert byte values

    링크
    규칙topaz.stdlib.contract.byte-buffer-storage.rule

    Allocate buffers and convert byte values

    ByteBuffer.allocate accepts a nonnegative int length and an int initial value from 0 through 255. The initial value defaults to zero.

    The new buffer has exactly that many copies of the initial byte. Zero length is valid and still requires a valid initial byte.

    A negative length produces TPZ4001 at runtime. An invalid initial byte or an allocation that cannot be satisfied produces TPZ5001 at runtime.

    ByteBuffer.fromBytes converts an immutable Bytes value into a mutable ByteBuffer value containing the same bytes.

    ByteBuffer.toBytes converts the current buffer contents into an immutable Bytes value.

    ByteBuffer.length is a read-only byte count property. Buffer operations never change its length.

    Assignment, argument passing, return, capture, and aggregate storage follow collection value semantics.

    Supplied expressions evaluate once from left to right before allocation or conversion. These operations have no I/O effects.

    이유

    A fixed length gives binary algorithms stable byte positions. Explicit conversion distinguishes mutable construction from immutable byte data.

    Allocate zero-filled and initialized buffers

    링크
    main.tpzAllocate zero-filled and initialized buffers플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. io.writeLine(ByteBuffer.allocate(0).toBytes().toHex())
    4. io.writeLine(ByteBuffer.allocate(3).toBytes().toHex())
    5. io.writeLine(ByteBuffer.allocate(2, 255).toBytes().toHex())
    기대 출력종료 코드 0
    
    000000
    ffff
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 000000
    2. ffff

    Keep the original buffer and converted bytes unchanged

    링크
    main.tpzKeep the original buffer and converted bytes unchanged플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let source = "ab".encodeUtf8()
    4. let buffer = ByteBuffer.fromBytes(source)
    5. let independent = ByteBuffer.fromBytes(source)
    6. let before = buffer.toBytes()
    7. let mut alias = buffer
    8. alias.set(0, 99)
    9. io.writeLine(source.toHex())
    10. io.writeLine(before.toHex())
    11. io.writeLine(independent.toBytes().toHex())
    12. io.writeLine(buffer.toBytes().toHex())
    기대 출력종료 코드 0
    6162
    6162
    6162
    6162
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 6162
    2. 6162
    3. 6162
    4. 6162

    Reject a negative buffer length

    링크
    main.tpzReject a negative buffer length플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. ByteBuffer.allocate(-1)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Validate the initial byte of an empty buffer

    링크
    main.tpzValidate the initial byte of an empty buffer플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. ByteBuffer.allocate(0, -1)
    4. io.writeLine("after")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Validate the initial byte of an empty buffer

    링크
    main.tpzValidate the initial byte of an empty buffer플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. ByteBuffer.allocate(0, 256)
    4. io.writeLine("after")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Diagnostics

    링크

    Runtime value guard →

    Validate buffer regions before writing

    링크
    규칙topaz.stdlib.contract.byte-buffer-mutation.rule

    Validate buffer regions before writing

    ByteBuffer.get and ByteBuffer.set use zero-based byte indices from zero through length minus one. Get returns an int byte.

    ByteBuffer.set replaces one byte. ByteBuffer.fill replaces length bytes beginning at start. Both require values from 0 through 255.

    ByteBuffer.copy receives the source buffer, sourceStart, targetStart, and length in that order. The receiver is the destination.

    Fill and copy use byte intervals from each start to start plus length. Starts and lengths must be nonnegative. Every complete source and destination interval must fit its buffer without arithmetic overflow.

    A zero length region at the end of a buffer is valid. A start beyond the end is invalid even when length is zero.

    Copy observes the source interval before its first destination write. Copying within one buffer therefore supports overlap in either direction.

    Set, fill, and copy return unit. They require a let mut root binding and update its destination value under collection value semantics.

    The receiver and supplied arguments evaluate once from left to right. Every range and byte check finishes before the first write.

    An invalid index or region produces TPZ4001 at runtime. An invalid byte value produces TPZ5001 at runtime, including a fill of zero bytes.

    A rejected operation performs no buffer writes. Effects performed while evaluating its receiver or arguments remain visible.

    When several preconditions fail, the selected failing precondition is unspecified. The operation still completes every argument evaluation before validation and performs no writes.

    이유

    Checking complete regions prevents a malformed count from leaving half-written data. Reading the source interval before writing gives one result for every overlap direction.

    Copy overlapping regions and preserve an earlier buffer value

    링크
    main.tpzCopy overlapping regions and preserve an earlier buffer value플레이그라운드 열기 →
    1. import std.bytes { Bytes, ByteBuffer }
    2. import std.io
    3. import std.test
    4. let mut buffer = ByteBuffer.fromBytes(test.assertOk(Bytes.fromHex("000102030405")))
    5. let alias = buffer
    6. buffer.copy(buffer, 0, 1, 5)
    7. io.writeLine(buffer.toBytes().toHex())
    8. buffer.fill(2, 2, 255)
    9. buffer.set(0, 128)
    10. io.writeLine(buffer.toBytes().toHex())
    11. buffer.copy(buffer, 1, 0, 5)
    12. buffer.fill(6, 0, 0)
    13. buffer.copy(buffer, 6, 6, 0)
    14. io.writeLine(buffer.toBytes().toHex())
    15. io.writeLine(alias.toBytes().toHex())
    16. io.writeLine("{alias.get(0)}")
    기대 출력종료 코드 0
    000001020304
    8000ffff0304
    00ffff030404
    000102030405
    0
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 000001020304
    2. 8000ffff0304
    3. 00ffff030404
    4. 000102030405
    5. 0

    Keep an independent source buffer unchanged

    링크
    main.tpzKeep an independent source buffer unchanged플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let source = ByteBuffer.fromBytes("abc".encodeUtf8())
    4. let mut target = ByteBuffer.allocate(4, 0)
    5. target.copy(source, 1, 1, 2)
    6. io.writeLine(target.toBytes().toHex())
    7. io.writeLine(source.toBytes().toHex())
    기대 출력종료 코드 0
    00626300
    616263
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 00626300
    2. 616263

    Reject a read at the exclusive end

    링크
    main.tpzReject a read at the exclusive end플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. let buffer = ByteBuffer.allocate(2)
    3. buffer.get(2)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject a negative write index

    링크
    main.tpzReject a negative write index플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.set(-1, 0)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject a fill whose complete region does not fit

    링크
    main.tpzReject a fill whose complete region does not fit플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.fill(1, 2, 0)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject an empty copy beyond the buffer end

    링크
    main.tpzReject an empty copy beyond the buffer end플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.copy(buffer, 3, 2, 0)
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Reject an invalid byte at a valid write index

    링크
    main.tpzReject an invalid byte at a valid write index플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let mut buffer = ByteBuffer.allocate(1)
    4. buffer.set(0, -1)
    5. io.writeLine("after")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Validate the byte for a fill of zero bytes

    링크
    main.tpzValidate the byte for a fill of zero bytes플레이그라운드 열기 →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let mut buffer = ByteBuffer.allocate(1)
    4. buffer.fill(1, 0, 256)
    5. io.writeLine("after")
    기대 출력0이 아닌 종료 코드
    표준 출력 없음.
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    거절 단계 run. 종료 코드가 0이 아닙니다.

    Compute interoperable checksums and digests

    링크
    규칙topaz.stdlib.contract.bytes-digests.rule

    Compute interoperable checksums and digests

    Bytes.crc32 returns the unsigned CRC-32/ISO-HDLC value as an int from 0 through 4294967295.

    CRC-32 uses width 32, polynomial 0x04c11db7, reflected input and output, initial value 0xffffffff, and final XOR 0xffffffff.

    Bytes.sha256 and Bytes.sha512 implement FIPS 180-4 and return 32 and 64 digest bytes respectively.

    Bytes.hmacSha256 uses its receiver as the key and its argument as the message. It returns the 32-byte HMAC-SHA-256 value from RFC 2104.

    HMAC hashes a key longer than the 64-byte SHA-256 block before zero-padding it. Empty keys and messages are valid.

    Empty input is valid for every checksum and digest. CRC-32 of empty input is zero.

    These operations process stored bytes without decoding or normalization. Inputs remain unchanged and correctly typed calls have no data-dependent failure.

    The receiver and any message argument evaluate once in that order. No external state, random input, or I/O affects the result.

    Use toHex or toBase64 on a digest when a text encoding is required. Those encodings are separate from the digest bytes.

    이유

    Named standard algorithms must agree with independent implementations. Keeping digest bytes separate from their text representation makes the same digest usable in binary and text formats.

    Match established checksum and hash vectors

    링크
    main.tpzMatch established checksum and hash vectors플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. io.writeLine("{Bytes.empty().crc32()}")
    4. let checksum = "123456789".encodeUtf8().crc32()
    5. io.writeLine("{checksum}")
    6. io.writeLine("abc".encodeUtf8().sha256().toHex())
    7. io.writeLine("abc".encodeUtf8().sha512().toHex())
    8. io.writeLine("key".encodeUtf8().hmacSha256("The quick brown fox jumps over the lazy dog".encodeUtf8()).toHex())
    기대 출력종료 코드 0
    0
    3421780262
    ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
    ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
    f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 0
    2. 3421780262
    3. ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
    4. ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
    5. f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

    Distinguish raw DEFLATE from zlib framing

    링크
    규칙topaz.stdlib.contract.bytes-deflate.rule

    Distinguish raw DEFLATE from zlib framing

    Bytes.deflateCompress returns Ok with one complete raw RFC 1951 DEFLATE stream. It adds no zlib or gzip header or checksum.

    Bytes.deflateFixedCompress returns Ok with one final fixed Huffman block. Empty input is valid and the final unused bits are zero.

    Fixed Huffman compression accepts at most 268435456 input bytes. Larger inputs return Err with a string before producing output.

    Bytes.zlibFixedCompress applies the same fixed Huffman compression and input bound, with an RFC 1950 zlib header and Adler-32 trailer.

    The zlib stream declares a 32768-byte window and no preset dictionary. Its header bytes are 0x78 and 0x01.

    Bytes.deflateDecompress accepts raw streams containing stored, fixed Huffman, and dynamic Huffman blocks. It reconstructs the original bytes in Ok.

    The decoder consumes one complete stream. Malformed or truncated blocks, invalid back-references, and complete trailing bytes return Err with a string.

    Final unused padding bits are not decoded as data. A zlib or gzip wrapper is not a raw DEFLATE stream.

    Bytes.deflateDecompress reverses either raw compressor for every supported input. Bytes.zlibFixedCompress requires a zlib decoder because its wrapper is part of the result.

    Each receiver evaluates once and remains unchanged. The operations perform no I/O and errors expose no partially decoded Bytes.

    Compression does not promise a particular size reduction. Except for the fixed block and wrapper requirements, encoded byte choices may change while preserving the stream format.

    이유

    Raw DEFLATE and zlib are different wire formats. The fixed Huffman operation additionally specifies block coding, so it serves a distinct format requirement rather than another name for a general compressor.

    Recover bytes from a raw stream

    링크
    main.tpzRecover bytes from a raw stream플레이그라운드 열기 →
    1. import std.io
    2. import std.test
    3. let encoded = test.assertOk("hello".encodeUtf8().deflateCompress())
    4. io.writeLine(test.assertOk(encoded.deflateDecompress()).toHex())
    5. io.writeLine(test.assertOk("".encodeUtf8().deflateFixedCompress()).toHex())
    6. io.writeLine(test.assertOk("".encodeUtf8().zlibFixedCompress()).toHex())
    기대 출력종료 코드 0
    68656c6c6f
    0300
    7801030000000001
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f
    2. 0300
    3. 7801030000000001

    Decode a valid fixed Huffman stream

    링크
    main.tpzDecode a valid fixed Huffman stream플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("cb48cdc9c90700"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    68656c6c6f
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f

    Decode short nonfinal stored blocks

    링크
    main.tpzDecode short nonfinal stored blocks플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("000100feff41010100feff42"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    4142
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 4142

    Ignore stored block alignment bits

    링크
    main.tpzIgnore stored block alignment bits플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("f90100feff41"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    41
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 41

    Reject truncated streams and trailing bytes

    링크
    main.tpzReject truncated streams and trailing bytes플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "010100feff", "010000ffff00", "070000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).deflateDecompress()) {
    6. case Err(_) => io.writeLine("invalid DEFLATE")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    기대 출력종료 코드 0
    invalid DEFLATE
    invalid DEFLATE
    invalid DEFLATE
    invalid DEFLATE
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid DEFLATE
    2. invalid DEFLATE
    3. invalid DEFLATE
    4. invalid DEFLATE

    Read and write complete gzip members

    링크
    규칙topaz.stdlib.contract.bytes-gzip.rule

    Read and write complete gzip members

    Bytes.gzipCompress returns Ok with one RFC 1952 gzip member containing the receiver bytes. Empty input is valid.

    The compressor does not read a clock or derive a filename from its environment. The header timestamp is zero and optional name and comment fields are absent.

    Bytes.gzipDecompress accepts one member with compression method DEFLATE, including valid timestamp, operating system, extra field, name, comment, and header CRC fields.

    The decoder accepts stored, fixed Huffman, and dynamic Huffman DEFLATE blocks. It validates the member CRC-32 and uncompressed size modulo 4294967296.

    Reserved header flags, malformed optional fields, invalid compressed data, checksum mismatches, and truncation return Err with a string.

    A second member or other bytes after the member return Err. A Bytes value represents one complete compressed payload in this API.

    Decoding a successfully compressed value recovers the original bytes. A decoder failure never exposes a prefix of the output.

    The receiver evaluates once and remains unchanged. Compression and decompression perform no I/O and do not decode the payload as text.

    이유

    Standard header and block handling allows gzip data to move between programs. Requiring one complete member prevents unconsumed suffixes from being silently discarded.

    Recover empty and nonempty payloads

    링크
    main.tpzRecover empty and nonempty payloads플레이그라운드 열기 →
    1. import std.io
    2. import std.test
    3. for text in (["", "hello"]) {
    4. let encoded = test.assertOk(text.encodeUtf8().gzipCompress())
    5. io.writeLine(test.assertOk(encoded.gzipDecompress()).toHex())
    6. }
    기대 출력종료 코드 0
    
    68656c6c6f
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f

    Accept ordinary gzip header metadata

    링크
    main.tpzAccept ordinary gzip header metadata플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("1f8b0800010000000003010500faff68656c6c6f86a6103605000000"))
    5. match (encoded.gzipDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    68656c6c6f
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f

    Accept compressed gzip blocks

    링크
    main.tpzAccept compressed gzip blocks플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("1f8b08000000000000ffcb48cdc9c9070086a6103605000000"))
    5. match (encoded.gzipDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    68656c6c6f
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f

    Reject a truncated member and an invalid checksum

    링크
    main.tpzReject a truncated member and an invalid checksum플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["1f8b0800", "1f8b08000000000000ff010500faff68656c6c6f87a6103605000000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).gzipDecompress()) {
    6. case Err(_) => io.writeLine("invalid gzip")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    기대 출력종료 코드 0
    invalid gzip
    invalid gzip
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid gzip
    2. invalid gzip

    Use Zstandard frames and explicit effort levels

    링크
    규칙topaz.stdlib.contract.bytes-zstd.rule

    Use Zstandard frames and explicit effort levels

    Bytes.zstdCompress accepts an int level from 1 through 22. The default is 3 and other values return Err with a string.

    The level is a compression effort hint. The API does not promise a size ratio, execution time, or different bytes for every pair of levels.

    A successful call returns Ok with one RFC 8878 frame requiring no external dictionary. Empty input is valid.

    Bytes.zstdDecompress accepts one standard frame containing raw, RLE, or compressed blocks, with valid frame parameters and an optional content checksum.

    A frame requiring an unavailable dictionary, a malformed header or block, a size or checksum mismatch, and truncation return Err with a string.

    Skippable frames, additional frames, and other trailing bytes return Err. The entire input must represent one data frame.

    Decompression returns all uncompressed bytes in Ok or an error without a partial output. Compressing then decompressing preserves the input bytes.

    The receiver and explicit level expression evaluate once in that order. The input remains unchanged and the operation performs no I/O.

    이유

    A bounded level range keeps calls portable. A complete frame boundary and explicit dictionary failure make the returned bytes independent of hidden decoder state.

    Use the default and both supported level boundaries

    링크
    main.tpzUse the default and both supported level boundaries플레이그라운드 열기 →
    1. import std.io
    2. import std.test
    3. let source = "hello".encodeUtf8()
    4. io.writeLine(test.assertOk(test.assertOk(source.zstdCompress()).zstdDecompress()).toHex())
    5. for level in ([1, 22]) {
    6. io.writeLine(test.assertOk(test.assertOk(source.zstdCompress(level)).zstdDecompress()).toHex())
    7. }
    8. for level in ([0, 23]) {
    9. match (source.zstdCompress(level)) {
    10. case Err(_) => io.writeLine("invalid level")
    11. case Ok(_) => io.writeLine("accepted")
    12. }
    13. }
    기대 출력종료 코드 0
    68656c6c6f
    68656c6c6f
    68656c6c6f
    invalid level
    invalid level
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f
    2. 68656c6c6f
    3. 68656c6c6f
    4. invalid level
    5. invalid level

    Decode a valid Zstandard RLE block

    링크
    main.tpzDecode a valid Zstandard RLE block플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("28b52ffd20052b000041"))
    5. match (encoded.zstdDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    4141414141
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 4141414141

    Decode short nonfinal Zstandard raw blocks

    링크
    main.tpzDecode short nonfinal Zstandard raw blocks플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("28b52ffd20020800004109000042"))
    5. match (encoded.zstdDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    기대 출력종료 코드 0
    4142
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 4142

    Reject missing block data and trailing bytes

    링크
    main.tpzReject missing block data and trailing bytes플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "28b52ffd20052900006869", "28b52ffd200001000000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).zstdDecompress()) {
    6. case Err(_) => io.writeLine("invalid Zstandard")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    기대 출력종료 코드 0
    invalid Zstandard
    invalid Zstandard
    invalid Zstandard
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. invalid Zstandard
    2. invalid Zstandard
    3. invalid Zstandard

    Protect data with systematic Reed-Solomon codewords

    링크
    규칙topaz.stdlib.contract.bytes-reed-solomon.rule

    Protect data with systematic Reed-Solomon codewords

    Bytes.reedSolomon255223Protect accepts between 1 and 14614305 input bytes. Empty input and larger input return Err with a string.

    Input bytes are partitioned into consecutive 223-byte data chunks. The final chunk is padded with zero bytes to 223 bytes.

    Each output codeword contains its 223 data bytes followed by 32 parity bytes. Codewords are concatenated in input order.

    The result contains 255 times the ceiling of input length divided by 223 bytes. At most 65535 codewords are produced.

    Field arithmetic uses GF256 with primitive polynomial 0x11d and primitive element 2. Generator roots are the powers of that element from 0 through 31.

    Treat the first data byte as the highest-degree coefficient. Parity is the 32-byte remainder after multiplying the data polynomial by x to the power 32.

    The output contains no original length or additional framing. Callers must retain the input length to distinguish padding from original trailing zero bytes.

    The operation generates parity bytes. It does not detect or correct corruption in existing codewords.

    The receiver evaluates once and remains unchanged. Input bounds are checked before output allocation and failure exposes no codeword prefix.

    이유

    A field definition and systematic layout make parity interoperable. Keeping the original length outside the codeword avoids silently guessing which trailing zero bytes belong to the payload.

    Protect a zero byte with zero padding and parity

    링크
    main.tpzProtect a zero byte with zero padding and parity플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(test.assertOk(Bytes.fromArray([0])).reedSolomon255223Protect())
    5. io.writeLine("{encoded.toArray().length}")
    6. io.writeLine(encoded.slice(0, 4).toHex())
    7. io.writeLine(encoded.slice(223, 255).toHex())
    기대 출력종료 코드 0
    255
    00000000
    0000000000000000000000000000000000000000000000000000000000000000
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 255
    2. 00000000
    3. 0000000000000000000000000000000000000000000000000000000000000000

    Reject empty data before creating codewords

    링크
    main.tpzReject empty data before creating codewords플레이그라운드 열기 →
    1. import std.bytes { Bytes }
    2. import std.io
    3. match (Bytes.empty().reedSolomon255223Protect()) {
    4. case Err(_) => io.writeLine("empty data rejected")
    5. case Ok(_) => io.writeLine("accepted")
    6. }
    기대 출력종료 코드 0
    empty data rejected
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. empty data rejected

    Emit the specified parity for a nonzero payload

    링크
    main.tpzEmit the specified parity for a nonzero payload플레이그라운드 열기 →
    1. import std.io
    2. import std.test
    3. let encoded = test.assertOk("hello".encodeUtf8().reedSolomon255223Protect())
    4. io.writeLine(encoded.slice(0, 5).toHex())
    5. io.writeLine(encoded.slice(223, 255).toHex())
    기대 출력종료 코드 0
    68656c6c6f
    c7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd
    
    $ topaz run main.tpz · 대상 제품 5.21.3
    기대 결과

    기대 결과

    실행을 마칩니다. 종료 코드 0.

    기대 표준 출력
    1. 68656c6c6f
    2. c7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd

    메뉴

    다운로드 →