Skip to content

Randomness #8

@rpnfan

Description

@rpnfan

I have the impression that your random generator is not really random.

The follow Powershell script uses a good random algorithm:

param(
    [string]$SourceFolder = "M:\",            # Source folder
    [string]$DestinationFolder = "Q:\", # USB stick folder
    [string[]]$Extensions = @("mp3","flac")        # Extensions to include
)

# Ensure destination exists
if (-not (Test-Path $DestinationFolder)) {
    New-Item -ItemType Directory -Path $DestinationFolder | Out-Null
}

# Collect all matching files recursively
$files = Get-ChildItem -Path $SourceFolder -Recurse -File |
    Where-Object { $Extensions -contains $_.Extension.TrimStart(".").ToLower() }

if ($files.Count -eq 0) {
    Write-Host "No files found with the specified extensions."
    exit
}

# Get free space on destination drive (in bytes)
$driveLetter = (Get-Item $DestinationFolder).PSDrive.Name
$freeSpace   = (Get-PSDrive -Name $driveLetter).Free

Write-Host "Free space on ${driveLetter}: $([math]::Round($freeSpace / 1GB,2)) GB"

# Strong random generator
$cryptoRand = [System.Security.Cryptography.RandomNumberGenerator]::Create()
function Get-RandomIndex($max) {
    $bytes = New-Object byte[] 4
    $cryptoRand.GetBytes($bytes)
    $val = [BitConverter]::ToUInt32($bytes,0)
    return ($val % $max)
}

# Shuffle files randomly
$shuffled = $files | Sort-Object { Get-RandomIndex $files.Count }

# Select files until free space is filled
$selected = @()
$totalSize = 0
foreach ($file in $shuffled) {
    if ($totalSize + $file.Length -le $freeSpace) {
        $selected += $file
        $totalSize += $file.Length
    } else {
        break
    }
}

# Copy into flat folder with progress output
try {
    $i = 1
    foreach ($file in $selected) {
        $destPath = Join-Path $DestinationFolder $file.Name
        Write-Host ("[{0}/{1}] Copying: {2}" -f $i, $selected.Count, $file.FullName)
        Copy-Item -Path $file.FullName -Destination $destPath -Force
        $i++
    }
    Write-Host "Copied $($selected.Count) random files using $([math]::Round($totalSize / 1GB,2)) GB of space."
}
catch [System.Management.Automation.PipelineStoppedException] {
    Write-Host "Script interrupted by user. Exiting gracefully..."
}


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions