如何编码URI以安全地存储在TableServiceEntity的RowKey中?

时间:2012-09-21 13:32:03

标签: url uri azure-storage azure-table-storage

我真的,真的喜欢将URI存储为Azure表存储中的RowKey值。根据{{​​3}},RowKeys不能包含URI中常见的字符(/,\,#,?)。

解决方案似乎很简单:只需编码URI即可。但这不起作用。无论出于何种原因,可以插入包含序列 %2f (正斜杠的编码值)的任何值,但不会查询,即使'%2f'不是包含任何禁用的字符。

好的,那么base64编码怎么样?不。它产生偶尔的正斜杠字符,这是不允许的。

是否有一种编码字符串(URI)的方法,该字符串可以可靠地存储为Azure表中的RowKey?优选地,但不是必须地,人类可读的东西。

5 个答案:

答案 0 :(得分:2)

使用base64编码后替换/应该有效。 从Encoding and decoding a string that may have slashes in it

得到了这个建议

答案 1 :(得分:0)

几种可能性:

  1. 使用某些特定编码(例如,UTF-8)转换字节,然后将字节编码为十六进制。用它作为关键。但是,某些URI可能会很长,并且密钥会更长,因此您可能会遇到RowKey的最大长度。
  2. 哈希URI(例如,使用MD5)。十六进制编码这些字节并将其用作密钥。请注意,有可能发生冲突,但您的PartitionKey可能会消除这种机会。由于散列是恒定长度,因此最大RowKey长度不应该有问题。
  3. 我确信还有其他想法,我很想听听他们的意见。

答案 2 :(得分:0)

关闭主题但相关:我正在动态创建表,并且有代码可以在您需要时帮助您,尽管表和PK / RK的规则是完全不同的。 “^ [A-ZA-Z] [A-ZA-Z0-9] {2.62} $”,“

也许你可以用它来激发你自己的解决方案

解码字符串

        string edit1 = host
            .Replace("qqu", "_")
            .Replace("qqh", "-")
            .Replace("qqp", ".")

            // NOTE: qqn is reserved leading sequence

            .Replace("qqt", "qqu")
            .Replace("qqo", "qqp")
            .Replace("qqg", "qqh")
            ;

        if (edit1.StartsWith("qqn"))
        {
            edit1 = edit1.Substring(3, edit1.Length);
        }
        if (edit1.StartsWith("qq"))
        {
            edit1 = edit1.Substring(2, edit1.Length);
        }

对字符串进行编码的方法

            string edit1 = this.originalName.ToLower().Trim()
                .Replace("qqu", "qqt")
                .Replace("qqp", "qqo")
                .Replace("qqh", "qqg")

                // NOTE: qqn is reserved leading sequence

                .Replace("_", "qqu")
                .Replace("-", "qqh")
                .Replace(".", "qqp");

            string test = "qq";
            if (edit1.StartsWith(test))
                return test + "n" + edit1;

            test = "0";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "1";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "2";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "3";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "4";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "5";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "6";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "7";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "8";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "9";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

            test = "0";
            if (edit1.StartsWith(test))
                return "qq" + edit1;

答案 3 :(得分:0)

将URL(\,/,?)中的所有非法行密钥字符替换为URLS中非法的字符(例如<,>,%)

答案 4 :(得分:0)

from openmdao.main.api import Assembly, Component
from openmdao.lib.datatypes.api import Float, Array, List
from openmdao.lib.drivers.api import DOEdriver, SLSQPdriver, COBYLAdriver, CaseIteratorDriver
from pyopt_driver.pyopt_driver import pyOptDriver

import numpy as np


class component1(Component):

    x = Float(iotype='in')
    y = Float(iotype='in')
    term1 = Float(iotype='out')
    a = Float(iotype='in', default_value=1)

    def execute(self):
        x = self.x
        a = self.a

        term1 = a*x**2
        self.term1 = term1

        print "In comp1", self.name, self.a, self.x, self.term1

    def list_deriv_vars(self):
        return ('x',), ('term1',)

    def provideJ(self):

        x = self.x
        a = self.a
        dterm1_dx = 2.*a*x

        J = np.array([[dterm1_dx]])
        # print 'In comp1, J = %s' % J

        return J


class component2(Component):

    x = Float(iotype='in')
    y = Float(iotype='in')
    term1 = Float(iotype='in')
    f = Float(iotype='out')
    q = Array(np.zeros(2), iotype='in', dtype='float')

    def execute(self):

        y = self.y + self.q[0]
        x = self.x + self.q[1]
        term1 = self.term1
        f = term1 + x + y**2
        print 'in comp2 q = %s' % self.q
        self.f = f
        print "In comp2", self.name, self.x, self.y, self.term1, self.f



class summer(Component):


    total = Float(iotype='out', desc='sum of all f values')

    def __init__(self, size):
        super(summer, self).__init__()
        self.size = size

        self.add('fs', Array(np.zeros(size), iotype='in', desc='f values from all cases'))

    def execute(self):
        self.total = sum(self.fs)
        print 'In summer, fs = %s and total = %s' % (self.fs, self.total)


class assembly(Assembly):

    x = Float(iotype='in')
    y = Float(iotype='in')
    total = Float(iotype='out')

    def __init__(self, size):

        super(assembly, self).__init__()

        self.size = size

        self.add('a_vals', Array(np.zeros(size), iotype='in', dtype='float'))

        self.add('fs', Array(np.zeros(size), iotype='out', dtype='float'))

        for i in range(0, size):
            self.add('q_%d' % i, Array(np.zeros(2), iotype='in', dtype='float'))

        print 'in init a_vals = %s, fs = %s' % (self.a_vals, self.fs)

    def configure(self):

        # self.add('driver', SLSQPdriver())
        self.add('driver', pyOptDriver())
        self.driver.optimizer = 'SNOPT'
        # self.driver.pyopt_diff = True

        #create this first, so we can connect to it
        self.add('summer', summer(size=len(self.a_vals)))
        self.connect('summer.total', 'total')

        print 'in configure a_vals = %s' % self.a_vals
        # print 'in configure q = %s' % self.q


        # create instances of components
        for i in range(0, self.size):
            c1 = self.add('comp1_%d' % i, component1())
            c1.missing_deriv_policy = 'assume_zero'

            c2 = self.add('comp2_%d'%i, component2())
            self.connect('a_vals[%d]' % i, 'comp1_%d.a' % i)
            self.connect('x', ['comp1_%d.x' % i, 'comp2_%d.x' % i])
            self.connect('y', ['comp1_%d.y' % i, 'comp2_%d.y' % i])
            self.connect('comp1_%d.term1' % i, 'comp2_%d.term1' % i)
            self.connect('q_%d' % i, 'comp2_%d.q' % i)

            self.connect('comp2_%d.f' % i, 'summer.fs[%d]' % i)

            self.driver.workflow.add(['comp1_%d' % i, 'comp2_%d' % i])

        # self.connect('summer.fs[:]', 'fs[:]')
        self.driver.workflow.add(['summer'])

        # set up main driver (optimizer)
        self.driver.iprint = 1
        self.driver.maxiter = 100
        self.driver.accuracy = 1.0e-6
        self.driver.add_parameter('x', low=-5., high=5.)
        self.driver.add_parameter('y', low=0., high=5.)
        for i in range(0, self.size):
            self.driver.add_parameter('q_%d' % i, low=0., high=5.)
        self.driver.add_objective('summer.total')


if __name__ == "__main__":
    """ the result should be -1 at (x, y) = (-0.5, 0) """

    import time
    from openmdao.main.api import set_as_top
    a_vals = np.array([1., 1., 1., 1.])
    test = set_as_top(assembly(size=len(a_vals)))
    test.a_vals = a_vals
    print 'in main, test.a_vals = %s, test.fs = %s' % (test.a_vals, test.fs)
    test.x = 2.
    test.y = -5
    q = np.tile(np.arange(1., 3.), (4, 1))
    for i in range(0, len(a_vals)):
        exec('test.q_%d = q[%d]' % (i, i))
        exec('print test.q_%d' % i)
        print test.q_0, test.q_1, test.q_2, test.q_3

    tt = time.time()
    test.run()

    print "Elapsed time: ", time.time()-tt, "seconds"

    print 'result = ', test.summer.total
    print '(x, y) = (%s, %s)' % (test.x, test.y)
    print 'fs = %s' % test.fs
    print test.fs
    for i in range(0, len(a_vals)):
        exec('print test.q_%d' % i)