批处理之家's Archiver

victorwoo 发表于 2014-8-18 18:35

用 PowerShell 解析 eD2k 链接

[i=s] 本帖最后由 victorwoo 于 2014-8-18 18:38 编辑 [/i]

原始链接:[url=http://blog.vichamp.com/powershell/2014/08/18/use-powershell-to-exact-ed2k-link/]用 PowerShell 解析 eD2k 链接[/url]
发表日期:2014-08-18
[hr]
[img]http://blog.vichamp.com/img/2014-08-18-use-powershell-to-exact-ed2k-link.png[/img]

电骡的 eD2k 链接包含了丰富的信息。例如这个:[code]
ed2k://[i]file[/i]BingPinyinSetup[i]1.5.24.02.exe[/i]31485072[i]C8C9282E6112455E624EE82941E5BA00[/i]p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225[i]h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP[/i]s=http://blog.vichamp.com[i]s=http://www.baidu.com[/i]/[i]sources,127.0.0.1:1234,192.168.1.1:8888[/i]/
[/code]这给我们的第一感觉是可以用正则表达式来解析。我们观察一下它的规律,发现它是用 `|` 分割的字符串:[code]
ed2k://
file
BingPinyinSetup_1.5.24.02.exe
31485072
C8C9282E6112455E624EE82941E5BA00
p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225
h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP
s=http://www.abc.com/def.zip
s=http://www.vichamp.com/qq.zip
/
sources,127.0.0.1:1234,192.168.1.1:8888
/
[/code]还有一些规律:

* 从 `p=` 开始,后面的段都是可选的。
* `p=xxx`、`h=xxx`、`s=xxx`看起来像键值对。
* `s=` 可以有多个,sources 后面的 IP 和端口可以有多对。

根据这个规律,我们可以很容易地构造出正则表达式,并用 PowerShell 解析它。[code]
function Get-Ed2kLink {
    Param(
        [string]
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, HelpMessage = 'Enter an ed2k:// url')]
        $Link
    )

    $regex = [regex]@'
(?x)
\bed2k://
\[i]file\[/i](?<FILE[i]NAME>[^[/i]]+)
\[i](?<FILE[/i]SIZE>\d+)
\[i](?<FILE[/i]HASH>[0-9a-fA-F]+)
(?:\[i]p=(?:(?<HASH[/i]SET>[0-9a-fA-F]+):?)+)?
(?:\[i]h=(?<ROOT[/i]HASH>[0-9a-zA-Z]+))?
(?:\[i]s=(?<HTTP[/i]SOURCE>[^[i]]+))[/i]
\|\/
\[i]sources(?:,(?<SOURCES[/i]HOST>[0-9a-zA-Z.]+):(?<SOURCES[i]PORT>\d+))[/i]
|\/\b
'@
    $match = $regex.Match($Link)
    if ($match.Success) {
        $sourcesHost = $match.Groups['SOURCES_HOST'].Captures | Select-Object -ExpandProperty Value
        $sourcesPort = $match.Groups['SOURCES_PORT'].Captures | Select-Object -ExpandProperty Value
        $sources = @()
        for ($i = 0; $i -lt $sourcesHost.Length; $i++) {
            $sources += [PSCustomObject][Ordered]@{
                Host = $sourcesHost[$i]
                Port = $sourcesPort[$i]
            }
        }

        $result = [PSCustomObject][Ordered]@{
            File = $match.Groups['FILE_NAME'].Value;
            FileSize = $match.Groups['FILE_SIZE'].Value;
            FileHash = $match.Groups['FILE_HASH'].Value;
            HashSet = $match.Groups['HASH_SET'].Captures | Select-Object -ExpandProperty Value
            RootHash = $match.Groups['ROOT_HASH'].Value;
            HttpSource = $match.Groups['HTTP_SOURCE'].Captures | Select-Object -ExpandProperty Value
            Sources = $sources;
        }
    } else {
        $result = $null
    }

    return $result
}

Get-Ed2kLink 'ed2k://[i]file[/i]BingPinyinSetup[i]1.5.24.02.exe[/i]31485072[i]C8C9282E6112455E624EE82941E5BA00[/i]p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225[i]h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP[/i]s=http://www.abc.com/def.zip[i]s=http://www.vichamp.com/qq.zip[/i]/[i]sources,127.0.0.1:1234,192.168.1.1:8888[/i]/'
[/code]执行结果如下:[code]
File       : BingPinyinSetup_1.5.24.02.exe
FileSize   : 31485072
FileHash   : C8C9282E6112455E624EE82941E5BA00
HashSet    : {79A822E1788353E0B289D2ADD5DA3BDE, FB9BB40DEDB1D2307E9D734A6416704B, 0732B122C4ECF70065B181C92BF72400, 437958DF590D764DE1694F91AC085225}
RootHash   : HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP
HttpSource : {http://www.abc.com/def.zip, http://www.vichamp.com/qq.zip}
Sources    : {@{Host=127.0.0.1; Port=1234}, @{Host=192.168.1.1; Port=8888}}
[/code]注意一下,由于 `s=` 和 `sources` 节包含循环体,所以[b]不能[/b]直接用 PowerShell 的 `-cmatch` 表达式和 `$Matches` 变量,[b]必须[/b]用 .NET 的 `[regex]` 类来处理。

参考材料:

* [url=http://www.emule-project.net/home/perl/help.cgi?l=16&topic_id=509&rm=show_topic]eD2k 連結[/url]
* [url=http://prdownloads.sourceforge.net/emule/LinkCreator0.7.zip]Link Creator[/url] - 用于生成 eD2k 链接。

您也可以在这里[url=http://blog.vichamp.com/download/Get-Ed2kLink.ps1]下载[/url]完整的源代码。

523066680 发表于 2014-8-18 18:43

在[i]不能发挥作用的情况下,强烈要求去掉[i] 和[/i]

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.