微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用XSL创建XML文件的哈希

我试图找到一种方法来“散列”XML文件内容.从根本上说,需要比较一些传入文本节点的文本节点,我期望确保校验和是相同的.传入的文本节点已从表单提交返回,我需要确保它们不会被更改(在合理范围内,排除冲突).

这个架构非常糟糕,所以请不要问它!我被一些非常糟糕的自定义代码锁定在一个给定的sharepoint实现中,我需要解决这个问题.

是否有可以实现的良好的校验和/哈希函数?我需要检查大约100个文本节点.

听起来你需要一个 position-dependent checksum.你要求XSLT实现,还是仅仅是算法?

这是一个在C中的implementation of Fletcher’s checksum,这不应该很难移植到XSLT.

更新:下面是Fletcher校验和的XSLT 2.0改编版.它是否足够快,取决于您的数据大小和您拥有的时间.我很想知道你的考试是怎么回事.为了优化,我会尝试将xs:integer更改为xs:int.

请注意,我已将上面链接的实现的按位OR(|)替换为普通加法.我没有资格分析这个变化对uniformitynon-invertibility的影响,但只要你没有一个聪明的黑客试图恶意绕过你的校验和检查就好了.

请注意,由于上述更改,此实现将不会提供与Fletcher校验和(@MDBiker)的真实实现相同的结果.因此,您无法将此函数输出与Java的Fletcher16的输出进行比较.但是它总是会返回相同输入的相同结果(它是确定性的),因此您可以在两个文本字符串上比较此函数输出.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:foo="my.foo.org">

    <xsl:variable name="str1">The quick brown fox jumps over the lazy dog.</xsl:variable>
    <xsl:variable name="str2">The quick frown Box jumps over the hazy frog.</xsl:variable>

    <xsl:template match="/">
        Checksum 1: <xsl:value-of select="foo:checksum($str1)"/>    
        Checksum 2: <xsl:value-of select="foo:checksum($str2)"/>    
    </xsl:template>

    <xsl:function name="foo:checksum" as="xs:int">
        <xsl:param name="str" as="xs:string"/>
        <xsl:variable name="codepoints" select="string-to-codepoints($str)"/>
        <xsl:value-of select="foo:fletcher16($codepoints,count($codepoints),1,0)"/>
    </xsl:function>

    <!-- can I change some xs:integers to xs:int and help performance? -->
    <xsl:function name="foo:fletcher16">
        <xsl:param name="str" as="xs:integer*"/>
        <xsl:param name="len" as="xs:integer" />
        <xsl:param name="index" as="xs:integer" />
        <xsl:param name="sum1" as="xs:integer" />
        <xsl:param name="sum2" as="xs:integer"/>
        <xsl:choose>
            <xsl:when test="$index gt $len">
                <xsl:sequence select="$sum2 * 256 + $sum1"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:variable name="newSum1" as="xs:integer"
                    select="($sum1 + $str[$index]) mod 255"/>
                <xsl:sequence select="foo:fletcher16($str,$len,$index + 1,$newSum1,($sum2 + $newSum1) mod 255)" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
</xsl:stylesheet>

输出

Checksum 1: 65256    
    Checksum 2: 25689

关于用法的说明:你说你需要对“XML文件内容运行校验和.根本需要比较一些文本节点”.如果将文本节点传递给foo:checksum(),它将正常工作:将提取其字符串值.

仅供参考,我进行了性能测试,以计算535KB XML输入文件中文本节点的校验和.这是我使用的初始模板:

<xsl:template match="/">
    Checksum of input: <xsl:value-of
      select="sum(for $t in //text() return foo:checksum($t)) mod 65536"/>    
</xsl:template>

它使用Saxon PE完成了0.8秒.

或者:

如果文本量不是很大,那么简单地将字符串本身(而不是校验和)相互比较可能会更快更准确.但是,由于您的体系结构限制,您可能无法同时访问这两个文本节点…我不清楚您的描述.

原文地址:https://www.jb51.cc/xml/293119.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。