【问题标题】:Create random data file from Windows CMD/PowerShell从 Windows CMD/PowerShell 创建随机数据文件
【发布时间】:2020-10-24 20:08:23
【问题描述】:

我希望能够使用 CMD 或 PowerShell 在 Windows 中生成随机数据文件,生成的数据由随机文本的行和行组成。我已经设法使用以下命令在 PowerShell 中实现了这一点,但是生成 1MB 数据大约需要 1 分钟,这对于生成 GB 来说太慢了:

1..100000 | % { [System.Web.Security.Membership]::GeneratePassword(70, 3) >> C:/dummy.txt }

文件输出应如下:

YyS@ZRU98udC3q#R@5o7AR$*Bh44v22J!ekKSpIAgLQyp^pbBx
s8Wm589aYYH39@Arb2^ZRMPjx2UaEwHYkMmhgFaU$QyAU@@@WU
yB^!qo6e4x*eFvx%ZY7738&&FkhHXU24OCJCxfyQ7a%peo!$ap
...........
...........
$GVhMrkZfJbIkgAgri0w9lFVt6a^vXh6ev&jwPHGfoE!pVW85r

有人有什么建议吗?最好我可以在不需要外部工具的情况下执行此操作,因为创建此数据的脚本将在机器启动期间自动运行。

【问题讨论】:

  • 可以有重复的行吗?
  • 什么是“[方式]太慢”? 1 分钟,1 小时?
  • 你想要真正随机还是伪随机?可以有随机单词或其他字符串还是必须是随机字符?我的意思是我有一个 6 骰子 PW 生成器,可以让你使用量子数生成来选择伪随机或真正随机。
  • @DougMaurer 最好在稍后的管道中随机用于数据库目的。只要不是一遍又一遍地重复相同的字符串,Ben Personick 都可以。
  • @Scrattle 道歉,每 MB 大约 1 分钟太慢了,我已经更新了答案。

标签: windows powershell cmd


【解决方案1】:

您当前方法缓慢的原因是打开、写入和关闭同一个文件 100K 次的开销。将文件重定向运算符移到管道表达式之外,并且只产生一次上述开销:

1..100000 | % { [System.Web.Security.Membership]::GeneratePassword(70, 3) } >> .\dummy.txt

为了说明差异,以下是使用原始密码与将输出重定向移到外部的 1000 个密码的测量结果:

PS ~>
>> Measure-Command {
>>   1..1000 | % { [System.Web.Security.Membership]::GeneratePassword(70, 3) >> .\dummy.txt }
>> } |Select TotalMilliseconds

TotalMilliseconds
-----------------
        8881.9736


PS ~>
>> Measure-Command {
>>   1..1000 | % { [System.Web.Security.Membership]::GeneratePassword(70, 3) } >> .\dummy.txt
>> } |Select TotalMilliseconds

TotalMilliseconds
-----------------
          72.7485

仅用 1000 行就已经快了 >100 倍

【讨论】:

  • 不错的收获,很容易被我忽视(我!)
  • 我无法相信这种方法的速度有多快,仅仅从这种变化。我在一分钟内从大约 1MB 变成了 400MB。感谢您的帮助,这正是我想要的。
【解决方案2】:

这应该让你开始。要点是它使用 C# 来生成随机的东西。您可以控制要使用的字符。它使用 Linq,因此可以使其运行得更快,但与 PS 中的随机生成相比,您应该已经看到了巨大的性能提升。它将生成大小合理的文本文件,如果您想要 GB 大小的数据,您需要查看其他方法。

$code = @"
using System;
using System.Linq;

namespace HelloWorld
{
    public class Program$id
    {
        const string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private static Random random = new Random();
        
        public static string RandomString(int length) // infinitely faster than Get-Random in Powershell
        {
            return new string(Enumerable.Repeat(chars, length)
              .Select(s => s[random.Next(s.Length)]).ToArray());
        }

    }
}
"@

Add-Type -TypeDefinition $code -Language CSharp 
$lines = 100000
$lenght = 70
$outfile = "e:\temp\dummy.txt" # tweak as needed
$sb = [System.Text.StringBuilder]::new() # spin up a stringbuilder to hold characters
# create a string buffer with $lines of $length characters
1..$lines | % { 
    [void]$sb.AppendLine((Invoke-Expression "[HelloWorld.Program$id]::RandomString($lenght)"))
}
$sb.ToString() | Out-File $outfile # write out results
cat $outfile -Tail 10 # show last 10 lines in output file

这在我的系统上需要 2-3 秒(包括cat)。

【讨论】:

  • 感谢您的建议,我想我会接受已接受的答案,因为它涉及对我当前方法的微小更改,并显着加快了进程。
猜你喜欢
  • 1970-01-01
  • 2017-05-16
  • 2015-06-10
  • 2013-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多