基数为52到十进制,反之亦然

时间:2014-07-29 14:11:51

标签: c# c++ arrays colors

我正在尝试调整这个可以执行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

让我认为这可能是一个指针问题。

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:0)

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

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]);