Ada-SHA3实现的明智代码结构

Wos*_*ame 4 ada

我将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)

fly*_*lyx 6

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 <>),因此您需要使用区分记录。

  • “ Static_Predicate”是Ada2012。对于较早的Ada版本,您只需将“ Third_Dimension_Type”声明为“ Natural”,而不能强制其仅包含有效值之一。 (2认同)