如何在 PowerShell 中抑制溢出检查?

Chr*_*ler 6 powershell integer-overflow unchecked unchecked-conversion

PowerShell 似乎在算术运算和转换后执行边界检查。例如,以下操作失败:

[byte]$a = 255
$a++

$a = [byte]256
Run Code Online (Sandbox Code Playgroud)

有没有办法强制溢出或类型转换,而无需通过模或 C# 和 Add-Type 进行手动计算?

Bra*_*s83 7

您在 PowerShell 中想要的行为是可以实现的,不过,这有点麻烦;也许还有更好的方法。

如果您只是想要加密功能,那么值得一提的是,BCL 中已经内置了大量加密功能,并且可以从 PowerShell 完全访问它(MD5、SHA、RSA、X509,还有大量其他内容)。

但是,如果您执意要在 PowerShell 中执行未经检查的算术,那么这个 hack 应该可以满足您的需求(基本上我们正在嵌入 C# 代码,并使用未经检查的关键字):

$members = @' 
public static UInt32 ToUInt32(int value)
{
    unchecked
    {
        return (UInt32)value;
    }
}


public static byte ToByte(int value)
{
    unchecked
    {
        return (byte)value;
    }
}
'@;

$type = Add-Type -Name "Convert" -Namespace "Helpers" `
        -MemberDefinition $members -PassThru -ErrorAction SilentlyContinue;
Run Code Online (Sandbox Code Playgroud)

用法:

PS C:\Some\Folder> [Helpers.Convert]::ToUInt32(-1);
4294967295

PS C:\Some\Folder> [Helpers.Convert]::ToByte(-1);
255

PS C:\Some\Folder> [Helpers.Convert]::ToByte(256);
0
Run Code Online (Sandbox Code Playgroud)

值得注意的是:

  • 我们正在打电话[Helpers.Convert]::To...,但没有 [System.Convert]::To...
  • 如果您需要其他方法,则需要将实际的 C# 方法插入到$members代码顶部的块中。
  • Add-Type如果在同一个 PowerShell 会话中连续多次运行Namespace相同的Name组合,则会失败;您将保留之前注册的类型。-- 我添加了-ErrorAction SilentlyContinue忽略这个特定场景的内容。-- 这样,您可以将此代码转储到 .ps1 脚本中,并在每次使用它们的方法之前调用它,并且它们将始终存在。-- 但如果您正在修改 C# 代码并重新测试,您将需要在每次更改后更改类型名称;有点痛苦。


Neo*_*ian 1

PowerShell 是一种脚本语言,而不是一种编程语言,它不支持许多高级技术,例如重载运算符(在这种情况下这会很方便)。

要添加到您已经建议的内容中,您可以捕获错误。

[byte]$a = 255
try {$a++} catch {$a=1}
Run Code Online (Sandbox Code Playgroud)

或者编写您自己的函数并在其中做一些取模的乐趣。

  • 也许 `catch` 语句应该是 `$a=0`。 (2认同)