Private/New-FakeReplacement.ps1

function New-FakeReplacement {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)]
        [string] $DetectedType,

        [Parameter(Mandatory)]
        [AllowEmptyString()]
        [string] $OriginalValue
    )

    # Mask the sign bit to avoid Math.Abs(Int32.MinValue) overflow
    $rng = [System.Random]::new([System.BitConverter]::ToInt32([System.Guid]::NewGuid().ToByteArray(), 0) -band [System.Int32]::MaxValue)

    switch ($DetectedType) {
        'Email'            { return New-FakeEmail -Rng $rng }
        'IpAddress'        { return New-FakeIp -Rng $rng }
        'PhoneNumber'      { return '(555) 000-{0:D4}' -f $rng.Next(0, 9999) }
        'SSN'              { return '000-00-{0:D4}' -f $rng.Next(0, 9999) }
        'CreditCard'       { return '4111111111111{0:D4}' -f $rng.Next(1000, 9999) }
        'BearerToken'      { return New-FakeToken -Rng $rng }
        'CredentialUrl'    { return New-FakeCredentialUrl -OriginalValue $OriginalValue -Rng $rng }
        'Hostname'         { return 'internal-host-{0}.local' -f (New-RandomString -Charset 'abcdefghijklmnopqrstuvwxyz0123456789' -Length 6 -Rng $rng) }
        'HighEntropyString'{ return New-FakeApiKey -OriginalValue $OriginalValue -Rng $rng }
        'KeyNameMatch'     { return '[REDACTED-KEYNAME-{0}]' -f (New-RandomString -Charset 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' -Length 32 -Rng $rng) }
        default            { return '[REDACTED]' }
    }
}

function New-FakeEmail {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param([Parameter(Mandatory)] [System.Random] $Rng)

    $firstNames = @(
        'alex','blake','casey','dana','drew','emery','finley','harper',
        'jamie','jordan','kendall','logan','morgan','parker','quinn',
        'reese','riley','sage','skyler','taylor'
    )
    $domains = @('fakecorp.io', 'testmsp.net', 'sampleco.org', 'demolab.dev', 'sandboxco.net')

    $name   = $firstNames[$Rng.Next(0, $firstNames.Count)]
    $suffix = $Rng.Next(10, 999)
    $domain = $domains[$Rng.Next(0, $domains.Count)]

    return '{0}{1}@{2}' -f $name, $suffix, $domain
}

function New-FakeIp {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param([Parameter(Mandatory)] [System.Random] $Rng)

    return '192.168.{0}.{1}' -f $Rng.Next(0, 255), $Rng.Next(1, 254)
}

function New-FakeToken {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [System.Random] $Rng
    )

    $suffix = New-RandomString -Charset 'abcdef0123456789' -Length 8 -Rng $Rng
    return '[REDACTED-TOKEN-{0}]' -f $suffix
}

function New-FakeCredentialUrl {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [string]       $OriginalValue,
        [Parameter(Mandatory)] [System.Random] $Rng
    )

    # Replace only the user:pass portion, preserve scheme and host
    $fakeUser = New-RandomString -Charset 'abcdefghijklmnopqrstuvwxyz' -Length 8 -Rng $Rng
    $fakePass = New-RandomString -Charset 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' -Length 16 -Rng $Rng

    return [System.Text.RegularExpressions.Regex]::Replace(
        $OriginalValue,
        '(?<=://)[^:@/\s]+:[^@/\s]+(?=@)',
        ('{0}:{1}' -f $fakeUser, $fakePass)
    )
}

function New-FakeApiKey {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [string]       $OriginalValue,
        [Parameter(Mandatory)] [System.Random] $Rng
    )

    $charset = Resolve-ApiKeyCharset -Sample $OriginalValue
    return New-RandomString -Charset $charset -Length $OriginalValue.Length -Rng $Rng
}

function Resolve-ApiKeyCharset {
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [string] $Sample
    )

    if ($Sample -match '^[0-9a-f]+$')                              { return '0123456789abcdef' }
    if ($Sample -match '^[0-9A-F]+$')                              { return '0123456789ABCDEF' }
    if ($Sample -match '^[A-Za-z0-9+/]+=*$' -and $Sample.Length % 4 -eq 0) { return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' }
    if ($Sample -match '^[A-Za-z0-9_-]+$')                        { return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-' }
    return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
}

function New-RandomString {
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '',
        Justification = 'Pure in-memory value generator; performs no system state change.')]
    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [string]       $Charset,
        [Parameter(Mandatory)] [int]          $Length,
        [Parameter(Mandatory)] [System.Random] $Rng
    )

    $sb = [System.Text.StringBuilder]::new($Length)
    for ($i = 0; $i -lt $Length; $i++) {
        $null = $sb.Append($Charset[$Rng.Next(0, $Charset.Length)])
    }
    return $sb.ToString()
}