【问题标题】:Base 52 to decimal And vice versa conversionBase 52 到十进制 反之亦然转换
【发布时间】:2014-09-20 22:55:24
【问题描述】:

我正在尝试调整这段代码,它可以执行与 Base 52 之间的转换,我用它来存储从 C# 到 C++ 的 RGB 颜色信息:

public static string ColourToBase52(Color colour)
        {
            int value = colour.ToArgb() & 0x00FFFFFF; // Mask off the alpha channel.
            return ToBase52(value);
        }

        public static Color ColourFromBase52(string colour)
        {
            int value = FromBase52(colour);
            return Color.FromArgb(unchecked((int)(0xFF000000 | value)));
        }

        public static string ToBase52(int value)
        {
            char[] baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            int targetBase = baseChars.Length;

            int i = 32;
            char[] buffer = new char[i];

            do
            {
                buffer[--i] = baseChars[value % targetBase];
                value = value / targetBase;
            }
            while (value > 0);

            char[] result = new char[32 - i];
            Array.Copy(buffer, i, result, 0, 32 - i);

            return new string(result).PadLeft(5, 'a');
        }

        public static int FromBase52(string value)
        {
            char[] baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
            int targetbase = baseChars.Length;

            int multiplier = 1;
            int result = 0;

            for (int i = value.Length-1; i >= 0; --i)
            {
                int digit = Array.IndexOf(baseChars, value[i]);
                result += digit*multiplier;
                multiplier *= targetbase;
            }

            return result;
        }

对于我的 C++ 代码,我选择将获取和返回颜色值作为整数的函数与 Base 52 转换函数相结合:

struct DIFColor *DIFBase52ToColor(std::string c)
{
    const char *baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int targetBase = 52;

    int multiplier = 1;
    int result = 0;
    const char *d = c.c_str();

    for (int i = c.length() - 1; i >= 0; --i)
    {

        int digit = DIFGetPositionInArray(baseChars, sizeof(baseChars), c[i]);

        result += digit * multiplier;
        multiplier = multiplier * targetBase;
    }



    uint8_t b = result & 255;
    uint8_t g = (result >> 8) & 255;
    uint8_t r = (result >> 16) * 255;

    return CreateDIFColor(r,g,b);
}

std::string DIFColorToBase52(struct DIFColor *c)
{
    int rgb = ((c->r&0x0ff)<<16)|((c->g&0x0ff)<<8)|(c->b&0x0ff);

    const char *baseChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int targetBase = 52;

    int i = 32;
    char *buffer = new char[i];

    do
    {
         buffer[--i] = baseChars[rgb % targetBase];
         rgb = rgb / targetBase;
    }
    while (rgb > 0);

    char *result = new char[32 - i];

    DIFCopyCharArray((const char *)buffer, i, 0, 32 - i, result);

    std::string s((const char*)result);
    s.insert(s.begin(), 5 - s.size(), 'a');

    return s;

}

我还必须为数组操作创建两个函数:

int DIFGetPositionInArray(const char *array, size_t size, const char c)
{
    for (size_t i = 0; i < size; i++)
    {

                if (array[i] == c)

                    return (int)i;

    }
    return -1;
}

void DIFCopyCharArray(const char* source, int wheretostart, int wheretocopy, int numtocopy, char *dest)
{
    int c = wheretocopy;


    for(int i = wheretostart; i <= numtocopy; i++)
    {
        dest[c] = source[i];
        c++;
    }


}

但是,当我尝试通过健全性检查对其进行测试时,它失败了:

255,255,255 = 'aah1U' in Base52 RGB
aah1U = 1,245,59 in RGB

似乎每次我运行健全性检查时,都会产生不同的值:

255,255,255 = 'aah13' in Base52 RGB
aah13 = 1,245,59 in RGB

255,255,255 = 'aah1j' in Base52 RGB
aah1j = 1,245,59 in RGB

预期的输出是:

255,255,255 = 'cpqEN' in Base52 RGB
cpqEN = 255,255,255 in RGB

让我觉得这可能是一个指针问题。

【问题讨论】:

  • 您应该在调试器中逐行逐行运行您的程序,看看它做了什么。密切关注变量及其值。
  • 您的代码存在内存泄漏和非法内存访问。不要到处使用指针,C++ 在没有指针的情况下会更好。
  • 我已将问题缩小到数组复制功能(我认为)

标签: c# c++ arrays colors


【解决方案1】:

错误可能是您没有在任何地方终止result 字符串,这导致undefined behavior 如下:

std::string s((const char*)result);

这是因为std::string 构造函数在复制您传递给它的 C 样式字符串时会查找终止符。

您可以通过两种方式解决它:将终止符 '\0' 添加到 result,或者告诉 std::string 构造函数 result 的长度。

【讨论】:

  • 这样做后生成的输出不正确,但至少每次都是一样的
【解决方案2】:

问题在于数组复制函数不正确。应该是:

void DIFCopyCharArray(const char* source, int wheretostart, int wheretocopy, int numtocopy, char *dest)
{
    int c = wheretocopy;


    for(int i = wheretostart; c <= numtocopy; i++)
    {
        dest[c] = source[i];
        c++;
    }

    dest[c] = '\0';


}

另外,数组搜索功能不起作用,因为sizeof(baseChars) 返回 4,这不是元素的数量。

使用这样的函数:

int DIFGetPositionInArray(const char *array, int arrayElements, const char c)
{
    for (int i = 0; i < arrayElements; i++)
    {

                if (array[i] == c)

                    return i;

    }
    return -1;
}

然后这样称呼它;

DIFGetPositionInArray(baseChars,52,d[i]);

【讨论】:

    猜你喜欢
    • 2011-02-02
    • 2012-08-21
    • 2012-09-18
    • 1970-01-01
    • 2021-07-17
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多