【问题标题】:Efficient and reliable hash for SID/PSID高效可靠的 SID/PSID 哈希
【发布时间】:2016-01-25 20:07:50
【问题描述】:

我的应用程序需要将大量的PSIDs 转换为友好的域\用户名字符串。

这可以通过LookupAccountSid 完成。不幸的是,这个 API 需要在很多地方进行嗅探才能解析 SID,包括可能的网络调用。因此,我想缓存以前见过的 SID。

我目前正在使用哈希表 (CMap) 执行此操作,该哈希表由 SID 的字符串表示作为键,即ConvertSidToStringSid 的结果。这很好,但我想知道是否有一个众所周知的、有效的、可靠的 SID 哈希例程,所以我不必转换为字符串?

可能将 SID 复制到字节缓冲区并散列缓冲区?还是通过其他 API 遍历 SID 本身的结构?

【问题讨论】:

  • 您在谈论多少个 SID(以便您期望它产生可衡量的差异)?
  • 一个 SID 由多个 SID Components 组成,其中最后一个组件由 变量 个子权限值组成。由于此组件可以任意长,因此字符串表示可能是您的最佳选择。
  • 将 SID 作为一组字节散列应该可以很好地工作。

标签: c++ winapi hash


【解决方案1】:

可以存储 SID 结构的字节。 SID 结构的长度是可变的,因此您必须首先使用GetLengthSid 函数检索它。

这是我在 Qt 中使用的一个实现,用于将值存储在 QByteArray 中。

PSID sid = ...

// retreive the length in bytes of the sid structure
DWORD sidSize = GetLengthSid(sid);

// check that sidSize fits into QByteArray::fromRawData
Q_ASSERT(sidSize <= INT_MAX);

QByteArray baSid = QByteArray::fromRawData((char *) sid, sidSize);

QByteArray::fromRawData 只包装数据而不进行复制。如果你想要一个副本,使用构造函数QByteArray::QByteArray(const char *data, int size = -1)

然后您可以将字节数组存储在任何 Qt 容器中,例如 QSet

请注意GetLengthSid 返回DWORD(在我的系统上定义为unsigned long)并且fromRawData 接受int。那次对话我从来没有遇到任何问题,但我包含了一个值不是太大的测试,INT_MAX 宏来自climits 标头。

如果已经构造了fromRawData,则使用constData 可以轻松地将字节数组转换回PSID

PSID sid = (PSID) baSid.constData();

当没有构造fromRawData 时,我没有测试constData,但文档指出:

除非创建了 QByteArray 对象,否则数据会以 '\0' 结尾 来自原始数据。

不幸的是,这段代码依赖于 Qt 框架,但它也应该适用于其他容器,例如 std::vector

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    • 2014-10-06
    • 2014-08-06
    • 2017-02-20
    • 2010-11-03
    • 2011-11-18
    • 1970-01-01
    相关资源
    最近更新 更多