---
title: Locate a byte signature within a buffer
summary: Locate the first occurrence of a byte signature within a buffer.
status: draft
owner: saif-docgen
last_reviewed: 2026-09-15
library: SAIF.Framework.Common
reference_type: package
operation_id: OP-023
trigger: Caller looks for a file-format signature (e.g. the `PDF_FILE_HEADER` constant `"%PDF-"`) inside a binary payload
---

# Locate a byte signature within a buffer

Locate the first occurrence of a byte signature within a buffer, triggered when caller looks for a file-format signature (e.g. the `PDF_FILE_HEADER` constant `"%PDF-"`) inside a binary payload.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-023 |
| **Trigger** | Caller looks for a file-format signature (e.g. the `PDF_FILE_HEADER` constant `"%PDF-"`) inside a binary payload |
| **Inputs** | `input`, `searchFor` (or an ASCII `string`), `start`, `maxBytesToSearch` |
| **Outputs** | `int` index of the first match, or `-1` |
| **Primary components** | ``ByteExtensions.Search(this byte[] input, byte[] searchFor, int start = 0, int maxBytesToSearch = 0)` and the `string` overload` |
| **Entry point** | `Common/SAIF.Common/Extensions/ByteExtensions.cs` |

## Steps

1. The `string` overload converts the needle with `Encoding.ASCII.GetBytes` and delegates to the `byte[]` overload. ([BR-053](../business-rules.md#br-053-a-string-search-pattern-over-a-binary-payload-is-encoded-as-ascii%2C-not-unicode))
2. Initialise `found = -1`. Proceed only if the haystack is non-empty, the needle is non-empty, `start <= input.Length - searchFor.Length`, and the haystack is at least as long as the needle; otherwise return `-1`. ([BR-054](../business-rules.md#br-054-a-byte-search-returns--1-when-the-haystack-is-empty%2C-the-needle-is-empty%2C-the-needle-is-longer-than-the-haystack%2C-or-the-start-offset-leaves-too-few-bytes))
3. Iterate `i` from `start` to `input.Length - searchFor.Length`.
4. If `maxBytesToSearch > 0` and `i > maxBytesToSearch`, break out of the loop — a scan cap for large payloads. ([BR-055](../business-rules.md#br-055-a-byte-search-may-be-capped))
5. When `input[i]` equals the needle's first byte, compare the remaining needle bytes one by one; on the first mismatch abandon this position.
6. On a full match, record `found = i` and break.
7. Return `found`.

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
	Start(["Search called with<br>byte[] or string needle"]) --> Overload{"String overload?"}
	Overload -->|Yes| ToBytes["Convert needle to bytes<br>via Encoding.ASCII"]
	Overload -->|No| Guard
	ToBytes --> Guard["Initialise found = -1"]
	Guard --> GuardCheck{"Haystack/needle non-empty<br>and start offset valid?"}
	GuardCheck -->|No| ReturnNeg1(["Return -1"])
	GuardCheck -->|Yes| Loop["Iterate i from start to<br>input.Length - searchFor.Length"]
	Loop --> CapCheck{"maxBytesToSearch > 0<br>and i > max?"}
	CapCheck -->|Yes| BreakCap["Break loop (scan cap)"]
	CapCheck -->|No| FirstByte{"input[i] equals<br>needle's first byte?"}
	FirstByte -->|No| NextI["Advance to next i"]
	NextI --> Loop
	FirstByte -->|Yes| Compare{"Remaining needle<br>bytes match?"}
	Compare -->|No| NextI
	Compare -->|Yes| RecordFound["Record found = i;<br>break loop"]
	RecordFound --> ReturnFound(["Return found"])
	BreakCap --> ReturnFound
```

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources
- `Common/SAIF.Common/Extensions/ByteExtensions.cs`
