【发布时间】:2019-09-13 11:37:55
【问题描述】:
我使用 SHA3 规范作为 Ada 编程语言的学习示例。
规范包含一系列称为排列的数据结构,其中有七种,它们的区别仅在于能够处理不同数量的数据。它们包含一个三维“状态数组”,其中前两个维度始终为 mod 5,第三个维度为 mod N,其中 N 仅限于以下几个值: 25、50、100、200、400、800 和 1600。
我通常认为使用泛型来区分每个包变体,但区别是数字,而不是类型。
如何合理地设计我的包/记录类型?
我能想到的唯一方法就是简单地创建一组显式类型...
package Perm_25 is...
package Perm_50 is...
package Perm_100 is...
package Perm_200 is...
package Perm_400 is...
package Perm_800 is...
package Perm_1600 is...
显然这是荒谬的,因为它很费力并且需要我复制大量代码,这会导致不一致。
此外,我不相信 OOP 在这里会有所帮助,因为除了某些数组维度之外,类型实际上并没有什么不同。
我应该如何解决这个问题?
编辑:感谢用户 @flyx 提供使用 Static_Predicate 子类型和可区分记录类型的提示。使用该建议,我设法编译了以下代码...
package body SHA3 is
subtype Perm_w_Coeff_Type is Positive
with Static_Predicate
=> Perm_w_Coeff_Type in 1 | 2 | 4 | 8 | 16 | 32 | 64;
subtype Perm_l_Coeff_Type is Natural range 0 .. 6;
type State_Array_Type is array (Natural range <>, Natural range <>, Natural range <>) of Boolean;
-- (see FIPS202 section 3)
type KECCAK_p_Permutation (bPW : b_Permutation_Width; numRounds : Positive; W_Coeff : Perm_w_Coeff_Type) is
record
b : b_Permutation_Width := bPW;
-- initialise w based on a lookup table using b as its index
-- (see FIPS202 section 3.1, table 1)
w : Perm_w_Coeff_Type := (
case bPW is
when 25 => 1,
when 50 => 2,
when 100 => 4,
when 200 => 8,
when 400 => 16,
when 800 => 32,
when 1600 => 64
);
-- initialise l based on a lookup table using b as its index
-- (see FIPS202 section 3.1, table 1)
l : Perm_l_Coeff_Type := (
case bPW is
when 25 => 0,
when 50 => 1,
when 100 => 2,
when 200 => 3,
when 400 => 4,
when 800 => 5,
when 1600 => 6
);
n_sub_r : Positive := numRounds;
State_Array : State_Array_Type (0 .. 4, 0 .. 4, 0 .. W_Coeff);
end record;
procedure Run is
begin
null;
end Run;
end SHA3;
【问题讨论】:
-
Ada 在数字上制作通用包没有问题。
标签: ada