逆向或算法?

发布于 2024-12-09 13:14:53 字数 879 浏览 0 评论 0原文

我先描述一下我的情况。

我有一个十六进制值列表,称为 BaseID。它们的选择使得任意数量的它们之间的逻辑“或”将为您提供一个唯一的ID,称为FinalID。也就是说,我的BaseID值如下。

BaseID = { 0x01, 0x02, 0x04, 0x08, 0x10, ... }

关键点是我不知道在运行程序之前我将拥有多少个 BaseID(我确实得到当我运行程序时,它是从文件中读取的 BaseID 列表),或者 BaseID 总数中有多少将用于创建最终ID。这是根据我的程序的其他部分决定的。例如,以下是我的程序中可能有的两个 FinalID。

FinalID = ( 0x01 | 0x04 ) = 0x05

FinalID = ( 0x02 | 0x04 | 0x10 ) = 0x16

现在,对任意数量的 BaseID 使用 OR 运算是很简单的部分。我的问题是,我需要从 FinalID 中提取用于创建 FinalID 的 BaseID。由于我选择了 BaseID,一旦使用 OR 运算,它们将始终为我提供唯一的 FinalID,因此我知道任何给定的 FinalID 都是使用一组特定的 BaseID 创建的。请注意,也可以仅使用一个 BaseID 创建 FinalID,这相当于 FinalID = ( BaseID | 0x00 )。

我知道我必须做什么来提取用于创建任何特定 FinalID 的 BaseID;我必须获取所涉及的 BaseID 的完整列表,然后在每个元素组合之间使用 OR 运算符来找出哪个组合是否给出了特定的 FinalID。

然而我发现很难将这种逻辑转换成程序。我正在使用 C# 和 .NET 3.5 Framework。任何建议/想法将非常感激。代码示例受到高度赞赏。

提前致谢!

Let me first describe my situation.

I have a list of Hex values, which are called BaseID. They are chosen such that logical OR between any number of them will give you a unique ID which is called FinalID. That is, my BaseID values are as follows.

BaseID = { 0x01, 0x02, 0x04, 0x08, 0x10, ... }

The critical point is that I don't know how many BaseIDs that I will have before I run the program (I do get a list of BaseIDs once I run the program as it is read from a file), or how many out of the total number of the BaseIDs will be used to create the FinalID. It is decided based upon other parts of my program. For example, following are two FinalIDs that I might have in my program.

FinalID = ( 0x01 | 0x04 ) = 0x05

FinalID = ( 0x02 | 0x04 | 0x10 ) = 0x16

Now, using OR operation for any number of BaseIDs is the easy part. My problem is, I need to extract from FinalID the BaseIDs used to create that FinalID. Since I've chosen BaseIDs such that they, once the OR operation is used, will ALWAYS give me a unique FinalID, I know that any given FinalID is created using a specific set of BaseIDs. Note that a FinalID can be created using only one BaseID too which is the equivalent of FinalID = ( BaseID | 0x00 ).

I know what I have to do to extract the BaseIDs used to create any particular FinalID; I have to get the complete list of BaseIDs involved, then use OR operator among each and every comibnation of elements to find out if which combination gives the particular FinalID.

However I'm finding it hard to convert this logic into a program. I am using C# with .NET 3.5 Framework. Any suggestions/ideas would be very much appreciated. A code sample is highly appreciated.

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

落花浅忆 2024-12-16 13:14:54

好的,所以你已经有了一个位掩码...你需要做的就是将你的 FinalID 与每个可能的 BaseID 进行“AND” - 如果结果非零,则该 BaseID 会影响 FinalID:

// Or just go from 0... count and use 1 << x
foreach (int baseId in BaseIDs)
{
    if ((baseId & finalId) != 0)
    {
        ...
    }
}

我还建议你可以想要为此使用“flags”枚举,这将使您的语言集成方面的生活更简单。

Okay, so you've got a bitmask... all you need to do is "AND" your FinalID with each possible BaseID - if the result is non-zero, that BaseID contributed to the FinalID:

// Or just go from 0... count and use 1 << x
foreach (int baseId in BaseIDs)
{
    if ((baseId & finalId) != 0)
    {
        ...
    }
}

I would also suggest that you might want to use a "flags" enum for this, which will make your life simpler in terms of language integration.

鱼忆七猫命九 2024-12-16 13:14:54

这是我的建议:

        uint mask = 0x1;

        do
        {
            if ((finalId & mask) == mask)
            {
                // Base-ID found
            }
            mask <<= 1;
        }
        while (mask < finalId);

Here is my suggestion:

        uint mask = 0x1;

        do
        {
            if ((finalId & mask) == mask)
            {
                // Base-ID found
            }
            mask <<= 1;
        }
        while (mask < finalId);
澉约 2024-12-16 13:14:54

让我试试...

foreach(Id baseID in baseIDs)
{
    if(baseID & finalID != 0)
        results.Add(candidate);
}

应该不错。

Let me try...

foreach(Id baseID in baseIDs)
{
    if(baseID & finalID != 0)
        results.Add(candidate);
}

Should do nice.

剑心龙吟 2024-12-16 13:14:54

如果您有所有 BaseID 的列表,那么与 FinalID 执行 AND 操作应该会告诉您它是否已被使用。

逻辑

Assume allBaseIds are sorted from lower to higher
For each (var baseId in allBaseIds)
{
   // FinalId will always be greater then consisting baseIds
   if(finalId < baseId)
     break;

   // As each base id represents a different bit, so its AND should result in baseId itself.
   if((finalId AND baseId) == baseId)
   {
      // This base id was used to make this final id.
   }
   else
   {
     // this base id was not used to make this final id
   }
}

If you have the list of all BaseIDs, then doing an AND with FinalID should tell you whether it was used or not.

Logic

Assume allBaseIds are sorted from lower to higher
For each (var baseId in allBaseIds)
{
   // FinalId will always be greater then consisting baseIds
   if(finalId < baseId)
     break;

   // As each base id represents a different bit, so its AND should result in baseId itself.
   if((finalId AND baseId) == baseId)
   {
      // This base id was used to make this final id.
   }
   else
   {
     // this base id was not used to make this final id
   }
}
夢归不見 2024-12-16 13:14:54
var baseId = new int[] { 0x01, 0x02, 0x04, 0x08, 0x10 };
var finalId = 0x01|0x02|0x10;

foreach (var b in baseId)
{
    if ((finalId & b) == b)
    {
        Console.WriteLine(b);
    }
}

我将补充一点,使用 int 最多可以有 32 个 baseId,使用 long 最多可以有 64 个 baseId。理论上,使用 BigInteger 类您可以达到您想要的高度。

var baseId = new int[] { 0x01, 0x02, 0x04, 0x08, 0x10 };
var finalId = 0x01|0x02|0x10;

foreach (var b in baseId)
{
    if ((finalId & b) == b)
    {
        Console.WriteLine(b);
    }
}

I'll add that using int you can have up to 32 baseId and using long you can have up to 64 baseId. Using the BigInteger class theorically you could go as high as you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文