<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:output method="xml"/>

<!-- 
  Decode base64 encoded string as hex string.
--> 
  <xsl:template name="Base64ToHex">
    <xsl:param name="str"/>
    <xsl:call-template name="Base64ToHexRec">
      <xsl:with-param name="str" select="translate(
        normalize-space($str),' ','')"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="Base64ToHexRec">
    <xsl:param name="str"/>
    <xsl:variable name="len" select="string-length($str)"/>
    <xsl:choose>
      <xsl:when test="$len = 0"/>
      <xsl:when test="$len &gt; 4">
        <xsl:variable name="mid" select="4*floor($len div 8)"/>
        <xsl:call-template name="Base64ToHexRec">
          <xsl:with-param name="str" select="substring($str,1,$mid)"/>
        </xsl:call-template>
        <xsl:call-template name="Base64ToHexRec">
          <xsl:with-param name="str" select="substring($str,$mid+1)"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
<!-- 
  Decode base64 encoded string of length 4 as hex string of length 2/4/6.

  |111122|223333|444455|556666| 

  result hex digits:
  1,2 always
  3,4 if '444455' != '='
  5,6 if '556666' != '='
--> 
        <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF='),
        1,1)"/>

        <xsl:variable name="h2b1" select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0123012301230123012301230123012301230123012301230123012301230123='),
        1,1)"/>

        <xsl:choose>
          <xsl:when test="$h2b1 = '0'">
            <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0000000000000000111111111111111122222222222222223333333333333333='),
            2,1)"/>
          </xsl:when>

          <xsl:when test="$h2b1 = '1'">
            <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'4444444444444444555555555555555566666666666666667777777777777777='),
            2,1)"/>
          </xsl:when>

          <xsl:when test="$h2b1 = '2'">
            <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'88888888888888889999999999999999AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB='),
            2,1)"/>
          </xsl:when>

          <xsl:when test="$h2b1 = '3'">
            <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF='),
            2,1)"/>
          </xsl:when>
        </xsl:choose>

        <xsl:if test="not(contains($str,'=='))">
          <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF='),
          2,1)"/>

          <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0000111122223333444455556666777788889999AAAABBBBCCCCDDDDEEEEFFFF='),
          3,1)"/>

          <xsl:if test="not(contains($str,'='))">
            <xsl:variable name="h2b2" select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0123012301230123012301230123012301230123012301230123012301230123='),
            3,1)"/>
 
            <xsl:choose>
              <xsl:when test="$h2b2 = '0'">
                <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0000000000000000111111111111111122222222222222223333333333333333='),
                4,1)"/>
              </xsl:when>

              <xsl:when test="$h2b2 = '1'">
                <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'4444444444444444555555555555555566666666666666667777777777777777='),
                4,1)"/>
              </xsl:when>

              <xsl:when test="$h2b2 = '2'">
                <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'88888888888888889999999999999999AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB='),
                4,1)"/>
              </xsl:when>

              <xsl:when test="$h2b2 = '3'">
                <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF='),
                4,1)"/>
              </xsl:when>
            </xsl:choose>

            <xsl:value-of select="substring(translate($str,
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF='),
            4,1)"/>

          </xsl:if>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>


  <xsl:template match="/">
    <hex>
      <xsl:call-template name="Base64ToHex">
        <xsl:with-param name="str" select="."/>
      </xsl:call-template>
    </hex>
  </xsl:template>

</xsl:stylesheet>

