我将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...
Run Code Online (Sandbox Code Playgroud)
显然,这很荒谬,因为它很费力,并且需要我重复很多代码,这会导致不一致。
我也不相信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;
Run Code Online (Sandbox Code Playgroud)
subtype Third_Dimension_Type is Natural with
Static_Predicate => Third_Dimension_Type in 25 | 50 | 100 | 200 | 400 | 800 | 1600;
Run Code Online (Sandbox Code Playgroud)
我不知道“前两个维始终是mod 5”是什么意思,但是假设您的意思是它们有5个条目,则结果数据类型将类似于:
type Permutation (Third_Dimension : Third_Dimension_Type) is record
State : array (1..5, 1..5, 1..Third_Dimension) of Item_Type;
end record;
Run Code Online (Sandbox Code Playgroud)
请注意,您不能指定采用两个离散范围和一个不确定范围的数组类型(例如Third_Dimension_Type range <>),因此您需要使用区分记录。
| 归档时间: |
|
| 查看次数: |
82 次 |
| 最近记录: |