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

时间:2013-03-30 15:23:48

标签: powershell integer-overflow unchecked unchecked-conversion

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

[byte]$a = 255
$a++

$a = [byte]256

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

2 个答案:

答案 0 :(得分:2)

你想在PowerShell中实现的行为是可以实现的,但这有点像黑客攻击;也许还有更好的方法。

如果您只是想要加密功能,那么值得一提的是,已经内置了BCL的TON,它可以从PowerShell完全访问(MD5,SHA,RSA,X509,其他很多东西)太)。

但是如果你在PowerShell中执行未经检查的算术,那么这是一个应该给你你想要的东西(基本上我们是嵌入C#代码,并使用unchecked关键字):

$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;

<强>用法:

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

注意:

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

答案 1 :(得分:1)

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

要添加您已经建议的内容,您可以抓住错误。

[byte]$a = 255
try {$a++} catch {$a=1}

或者编写自己的函数并在那里做一些模数乐趣。