wget:拖网样本 space of 100000000,最多返回 100 个结果
wget: Trawl sample space of 100000000, max 100 results returned
不确定这是堆栈还是代码审查,因为我对解决问题的完全不同的方法持开放态度,尽管我是从 PowerShell 开始的,但并不拘泥于特定的语言或风格。
我目前正在使用我们无权访问后端的网络服务器。
它return是一个基于左对齐过滤器生成的证书列表,例如如果您在搜索框中键入 100 并单击提交,它将搜索所有以 100* 开头或范围 10000000 - 10099999
的证书
我们所有的证书都是八位数字,样本 space 为 00000000-99999999。我正在尝试查找在此示例 space 中实际存在的证书,因为证书名称必须是唯一的。
主要注意事项是服务器只会 return 前 100 个结果,如果您的查询 return 多于该范围内现有证书的 100 个以上的结果, extras 被丢弃。
我的第一个方法是只使用 wget(从技术上讲是 PowerShell 的 Invoke-WebRequest)并遍历查询范围 000000 到 999999(一次 100 个),这是有效的,我在 9 月中旬按计划进行完成。
不幸的是,有些人希望尽快获得这些数据,所以我不得不编写一个递归函数(使用我的默认输入)一次查询一千万个证书的大样本 space 并搜索一个逐渐变小 space 直到 < 99 个证书被 return 每个子spaceed,然后移动到下一个一千万。
数据分布不均匀或不可预测,'most'(~90%?)证书集中在 10000000-19999999 和 30000000-39999999 左右,但我需要它们。
这是我目前正在使用的功能,它似乎在工作(结果正在写入文件,并且比以前更快),但它仍在进行中。有没有:
- 函数的明显错误
- 更好的输入选择(以提高效率)
- 完全不同的方法会更好
变量“$certsession”在此代码段之外建立,表示网络服务器会话(登录信息、cookie 等)
function RecurseCerts ($min,$max,$step,$level) {
for ($certSpace = $min; $certSpace -le $max; $certSpace += $step) {
$levelMultiplier = "0" * $level
#Assuming a level of 3, these ToString arguments would turn a '5' into 005, a '50' into 050, and so on. Three or more digit numbers are unchanged.
$query = ($certSpace).ToString($levelMultiplier)
$resultsArray = New-Object System.Collections.ArrayList
"Query is $query"
#Get webpage, split content by newline, search for lines with a certificate common name and add them to the results array
Invoke-WebRequest -uri "https://webserver.com/app?service=direct%2F1%2FSearchPage%2F%24Form&sp=S0&Form0=%24TextField%2C%24Submit&%24TextField=$query&%24Submit=Search" -websession $certsession | %{$_.content -split "`n" | %{if ($_ -match "cn=(.*?),ou") {$resultsArray = $resultsArray + $matches[1]}}}
#If we got more than 98 results for our query, make the search more specific, until we don't get more than 98 (else condition).
if ($resultsArray.count -gt 98) {"Recursing at $certSpace"; $subLevel = $level + 1; $subSpace = $certSpace * 10; RecurseCerts -min $subSpace -max ($subSpace + 9) -step 1 -level $subLevel}
#This is the most specific 0-98 for this range, write it out to the file
else {"Completed range $certspace"; $resultsArray | out-file c:\temp\certlist.txt -encoding utf8 -append}
}
}
#Level 3 means include rightmost 3 digits eg. search 101 for range 10100000 - 10199999
#Level 4 would be the subspace 1010-1019 (so a search for 1015 returns 10150000 - 10159999)
RecurseCerts -min 0 -max 9 -step 1 -level 1
由于我添加了 'language agnostic',请随时询问任何需要的 PowerShell 说明。如果需要,我也可以尝试用伪代码重写它。
我认为范围已经迭代的事实应该可以防止在使用 subspace 完成并跳回到更高级别时重复(重新捕获它已经在较低级别捕获的东西应该是阻止),但如果我说我完全理解这里的程序流程,那我就是在撒谎。
如果发现有重复,我可以过滤文本文件以查找重复项。但是,我仍然对消除此问题的方法感兴趣(如果存在的话)。
*我更新了代码以向控制台显示进度指示器,并且根据建议还更改了用于 arraylist 的数组类型。服务器非常脆弱,所以我暂时避免使用多线程,但它通常是像这样的任务的有用功能 - here's a summary of some ways to do this in PowerShell.
这是当前行为的示例。值得注意的是,整个一千万范围 00000000 - 09999999 的证书少于 98 个,因此无需递归即可处理。
RecurseCerts behaviour
将我的评论移至答案:
第一个建议:授权访问后端。
性能提升的大空间是 threading/split 在多个客户端上工作。由于它只是一个很大的 space 数字,您可以轻松地:
- 有两个 PowerShell 进程 运行ning,在一个中搜索 00000000-49999999,在另一个中搜索 50000000-99999999(或任意数量的进程)。
- 有两台电脑做,如果你有其他人访问
- 使用 PowerShell 多处理(线程、作业、工作流),尽管这些使用起来更复杂。
- 由于这主要是 server/network 缓慢,可能不值得使用更困难的技术,但是使用 start/end 数字和 运行 两次的脚本会很容易.
代码$resultsArray = $resultsArray + $matches[1]
很慢;数组是不可变的(固定大小),因此这会导致 PowerShell 创建一个新数组并将该数组复制到其中。在一个循环中,添加成千上万的东西,会产生很大的开销。请改用 $a = [System.Collections.ArrayList]@()
和 $a.Add($thing)
。
服务器响应速度有多快(是在局域网上还是在互联网上)?如果它是通过 WAN 连接的,那么你的速度会有延迟限制,但是如果它正在搜索一个大数据库并且需要一段时间才能 return 一个页面,那么你可以从客户端。
响应页面有多大? Invoke-WebRequest
将 HTML 解析为完整的 DOM 并且它非常慢,而且您没有使用 DOM 所以您不需要它。您可以使用 [System.Net.WebClient]
将内容下载为字符串:
例如
$web = New-Object System.Net.WebClient
$web.DownloadString($url)
- 在设计方面,您希望在 100M 搜索中有多少个证书space? 1万? 50公尺?您的递归函数可能会一遍又一遍地搜索、提取和忽略相同的证书,以试图使其低于 100。根据分布情况,我很想寻找并屏蔽具有 0 个证书的最大块。如果您可以在一个非常有用的请求中排除 1M 的范围。搜索 1M,发现太多证书,搜索 500K,太多,[...] 搜索 10K 发现太多,看起来既浪费又慢。
不确定这是堆栈还是代码审查,因为我对解决问题的完全不同的方法持开放态度,尽管我是从 PowerShell 开始的,但并不拘泥于特定的语言或风格。
我目前正在使用我们无权访问后端的网络服务器。
它return是一个基于左对齐过滤器生成的证书列表,例如如果您在搜索框中键入 100 并单击提交,它将搜索所有以 100* 开头或范围 10000000 - 10099999
的证书我们所有的证书都是八位数字,样本 space 为 00000000-99999999。我正在尝试查找在此示例 space 中实际存在的证书,因为证书名称必须是唯一的。
主要注意事项是服务器只会 return 前 100 个结果,如果您的查询 return 多于该范围内现有证书的 100 个以上的结果, extras 被丢弃。
我的第一个方法是只使用 wget(从技术上讲是 PowerShell 的 Invoke-WebRequest)并遍历查询范围 000000 到 999999(一次 100 个),这是有效的,我在 9 月中旬按计划进行完成。
不幸的是,有些人希望尽快获得这些数据,所以我不得不编写一个递归函数(使用我的默认输入)一次查询一千万个证书的大样本 space 并搜索一个逐渐变小 space 直到 < 99 个证书被 return 每个子spaceed,然后移动到下一个一千万。
数据分布不均匀或不可预测,'most'(~90%?)证书集中在 10000000-19999999 和 30000000-39999999 左右,但我需要它们。
这是我目前正在使用的功能,它似乎在工作(结果正在写入文件,并且比以前更快),但它仍在进行中。有没有:
- 函数的明显错误
- 更好的输入选择(以提高效率)
- 完全不同的方法会更好
变量“$certsession”在此代码段之外建立,表示网络服务器会话(登录信息、cookie 等)
function RecurseCerts ($min,$max,$step,$level) {
for ($certSpace = $min; $certSpace -le $max; $certSpace += $step) {
$levelMultiplier = "0" * $level
#Assuming a level of 3, these ToString arguments would turn a '5' into 005, a '50' into 050, and so on. Three or more digit numbers are unchanged.
$query = ($certSpace).ToString($levelMultiplier)
$resultsArray = New-Object System.Collections.ArrayList
"Query is $query"
#Get webpage, split content by newline, search for lines with a certificate common name and add them to the results array
Invoke-WebRequest -uri "https://webserver.com/app?service=direct%2F1%2FSearchPage%2F%24Form&sp=S0&Form0=%24TextField%2C%24Submit&%24TextField=$query&%24Submit=Search" -websession $certsession | %{$_.content -split "`n" | %{if ($_ -match "cn=(.*?),ou") {$resultsArray = $resultsArray + $matches[1]}}}
#If we got more than 98 results for our query, make the search more specific, until we don't get more than 98 (else condition).
if ($resultsArray.count -gt 98) {"Recursing at $certSpace"; $subLevel = $level + 1; $subSpace = $certSpace * 10; RecurseCerts -min $subSpace -max ($subSpace + 9) -step 1 -level $subLevel}
#This is the most specific 0-98 for this range, write it out to the file
else {"Completed range $certspace"; $resultsArray | out-file c:\temp\certlist.txt -encoding utf8 -append}
}
}
#Level 3 means include rightmost 3 digits eg. search 101 for range 10100000 - 10199999
#Level 4 would be the subspace 1010-1019 (so a search for 1015 returns 10150000 - 10159999)
RecurseCerts -min 0 -max 9 -step 1 -level 1
由于我添加了 'language agnostic',请随时询问任何需要的 PowerShell 说明。如果需要,我也可以尝试用伪代码重写它。
我认为范围已经迭代的事实应该可以防止在使用 subspace 完成并跳回到更高级别时重复(重新捕获它已经在较低级别捕获的东西应该是阻止),但如果我说我完全理解这里的程序流程,那我就是在撒谎。
如果发现有重复,我可以过滤文本文件以查找重复项。但是,我仍然对消除此问题的方法感兴趣(如果存在的话)。
*我更新了代码以向控制台显示进度指示器,并且根据建议还更改了用于 arraylist 的数组类型。服务器非常脆弱,所以我暂时避免使用多线程,但它通常是像这样的任务的有用功能 - here's a summary of some ways to do this in PowerShell.
这是当前行为的示例。值得注意的是,整个一千万范围 00000000 - 09999999 的证书少于 98 个,因此无需递归即可处理。
RecurseCerts behaviour
将我的评论移至答案:
第一个建议:授权访问后端。
性能提升的大空间是 threading/split 在多个客户端上工作。由于它只是一个很大的 space 数字,您可以轻松地:
- 有两个 PowerShell 进程 运行ning,在一个中搜索 00000000-49999999,在另一个中搜索 50000000-99999999(或任意数量的进程)。
- 有两台电脑做,如果你有其他人访问
- 使用 PowerShell 多处理(线程、作业、工作流),尽管这些使用起来更复杂。
- 由于这主要是 server/network 缓慢,可能不值得使用更困难的技术,但是使用 start/end 数字和 运行 两次的脚本会很容易.
代码
$resultsArray = $resultsArray + $matches[1]
很慢;数组是不可变的(固定大小),因此这会导致 PowerShell 创建一个新数组并将该数组复制到其中。在一个循环中,添加成千上万的东西,会产生很大的开销。请改用$a = [System.Collections.ArrayList]@()
和$a.Add($thing)
。服务器响应速度有多快(是在局域网上还是在互联网上)?如果它是通过 WAN 连接的,那么你的速度会有延迟限制,但是如果它正在搜索一个大数据库并且需要一段时间才能 return 一个页面,那么你可以从客户端。
响应页面有多大?
Invoke-WebRequest
将 HTML 解析为完整的 DOM 并且它非常慢,而且您没有使用 DOM 所以您不需要它。您可以使用[System.Net.WebClient]
将内容下载为字符串:
例如
$web = New-Object System.Net.WebClient
$web.DownloadString($url)
- 在设计方面,您希望在 100M 搜索中有多少个证书space? 1万? 50公尺?您的递归函数可能会一遍又一遍地搜索、提取和忽略相同的证书,以试图使其低于 100。根据分布情况,我很想寻找并屏蔽具有 0 个证书的最大块。如果您可以在一个非常有用的请求中排除 1M 的范围。搜索 1M,发现太多证书,搜索 500K,太多,[...] 搜索 10K 发现太多,看起来既浪费又慢。