亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? polyfact.c

?? 應用密碼學這本書的源代碼
?? C
字號:
/*
  Author:  Pate Williams (c) 1997

  Berlekamp's Q-matrix algorithm. See "Handbook
  of Applied Cryptography" by Alfred J. Menezes
  et al 3.11.2 Section 3.111 Algorithm page 124.
  Also see "Seminumerical Algorithms" by Donald
  E. Knuth second edition page 423 and "A Course
  in Computational Algebraic Number Theory" by
  Henri Cohen Algorithm 3.4.10 page 132.
*/

#include <assert.h>
#include <malloc.h>
#include <stdio.h>
#include "lip.h"

#define DEBUG
#define POLY_SIZE 8192l

verylong **create_matrix(long m, long n)
{
  long i;
  verylong **matrix = calloc(m, sizeof(verylong));

  assert(matrix != 0);
  for (i = 0; i < m; i++) {
    matrix[i] = calloc(n, sizeof(verylong));
    assert(matrix[i] != 0);
  }
  return matrix;
}

void delete_matrix(long m, verylong **matrix)
{
  long i;

  for (i = 0; i < m; i++) free(matrix[i]);
  free(matrix);
}

void zpoly_mul(long m, long n, verylong *za, verylong *zb,
               verylong *zc, long *p)
{
  long i, j, k;
  verylong zd = 0, zai = 0, zbk = 0, zsum = 0, zterm = 0;

  *p = m + n;
  for (k = 0; k <= *p; k++) {
    zzero(&zsum);
    for (i = 0; i <= k; i++) {
      j = k - i;
      if (i > m) zzero(&zai);
      else zcopy(za[i], &zai);
      if (j > n) zzero(&zbk);
      else zcopy(zb[j], &zbk);
      zmul(zai, zbk, &zterm);
      zcopy(zsum, &zd);
      zadd(zterm, zd, &zsum);
    }
    zcopy(zsum, &zc[k]);
  }
  zfree(&zd);
  zfree(&zai);
  zfree(&zbk);
  zfree(&zsum);
  zfree(&zterm);
}

void zpoly_div(long m, long n, verylong *zu, verylong *zv,
               verylong *zq, verylong *zr, long *p, long *s)
{
  long j, jk, k, nk;
  verylong za = 0, zb = 0, zvn = 0;

  zcopy(zv[n], &zvn);
  for (j = 0; j <= m; j++)
    zcopy(zu[j], &zr[j]);
  if (m < n) {
    *p = 0, *s = m;
    zzero(&zq[0]);
  }
  else {
    *p = m - n, *s = n - 1;
    for (k = *p; k >= 0; k--) {
      nk = n + k;
      zsexp(zvn, k, &za);
      zmul(zr[nk], za, &zq[k]);
      for (j = nk - 1; j >= 0; j--) {
        jk = j - k;
        if (jk >= 0) {
          zmul(zvn, zr[j], &za);
          zmul(zr[nk], zv[jk], &zb);
          zsub(za, zb, &zr[j]);
        }
        else {
          zcopy(zr[j], &za);
          zmul(zvn, za, &zr[j]);
        }
      }
    }
    while (*p > 0 && zscompare(zq[*p], 0l) == 0) *p = *p - 1;
    while (*s > 0 && zscompare(zr[*s], 0l) == 0) *s = *s - 1;
  }
  zfree(&za);
  zfree(&zb);
  zfree(&zvn);
}

void zpoly_mod(long p, verylong *za, long *da)
{
  long i;

  for (i = 0; i <= *da; i++)
    zintoz(zsmod(za[i], p), &za[i]);
  while (*da > 0 && zscompare(za[*da], 0l) == 0) *da = *da - 1;
}

void zpoly_pow(long degreeA, long degreem, long p,
               verylong zn, verylong *zA,
               verylong *zm, verylong *zs,
               long *ds)
{
  long dp, dq, dx = degreeA, i;
  verylong za = 0, zb = 0, zp[POLY_SIZE], zq[POLY_SIZE],
           zx[POLY_SIZE], zy[POLY_SIZE];

  for (i = 0; i < POLY_SIZE; i++)
    zp[i] = zq[i] = zx[i] = zy[i] = 0;
  *ds = 0;
  zcopy(zn, &za);
  zone(&zs[0]);
  for (i = 0; i <= dx; i++) zcopy(zA[i], &zx[i]);
  while (zscompare(za, 0l) > 0) {
    if (zodd(za)) {
      /* s = (s * x) % m; */
      zpoly_mul(*ds, dx, zs, zx, zp, &dp);
      zpoly_div(dp, degreem, zp, zm, zq, zs, &dq, ds);
      zpoly_mod(p, zs, ds);
    }
    zcopy(za, &zb);
    zrshift(zb, 1l, &za);
    if (zscompare(za, 0l) > 0) {
      /* x = (x * x) % m; */
      for (i = 0; i <= dx; i++) zcopy(zx[i], &zy[i]);
      zpoly_mul(dx, dx, zx, zy, zp, &dp);
      zpoly_div(dp, degreem, zp, zm, zq, zx, &dq, &dx);
      zpoly_mod(p, zx, &dx);
    }
  }
  zfree(&za);
  zfree(&zb);
  for (i = 0; i < POLY_SIZE; i++) {
    zfree(&zp[i]);
    zfree(&zq[i]);
    zfree(&zx[i]);
    zfree(&zy[i]);
  }
}

void zpoly_sub(long da, long db, verylong *za, verylong *zb,
               verylong *zc, long *dc)
{
  long i;
  verylong zz = 0;

  zzero(&zz);
  if (da >= db) {
    for (i = 0; i <= db; i++)
      zsub(za[i], zb[i], &zc[i]);
    for (i = db + 1; i <= da; i++)
      zcopy(za[i], &zc[i]);
    *dc = da;
  }
  else {
    for (i = 0; i <= da; i++)
      zsub(za[i], zb[i], &zc[i]);
    for (i = da + 1; i <= db; i++)
      zsub(zz, zb[i], &zc[i]);
    *dc = db;
  }
  zfree(&zz);
}

void zpoly_gcd(long degreeA, long degreeB, long p,
               verylong *zA, verylong *zB, verylong *za,
               long *da)
{
  int nonzero = 0, zero;
  long db, dq, dr, i;
  verylong zc = 0, zd = 0, zp = 0;
  verylong zb[POLY_SIZE], zq[POLY_SIZE], zr[POLY_SIZE];

  for (i = 0; i < POLY_SIZE; i++)
    zb[i] = zq[i] = zr[i] = 0;
  if (degreeA > degreeB) {
    *da = degreeA;
    db = degreeB;
    for (i = 0; i <= *da; i++) zcopy(zA[i], &za[i]);
    for (i = 0; i <= db; i++) zcopy(zB[i], &zb[i]);
  }
  else {
    *da = degreeB;
    db = degreeA;
    for (i = 0; i <= *da; i++) zcopy(zB[i], &za[i]);
    for (i = 0; i <= db; i++) zcopy(zA[i], &zb[i]);
  }
  for (i = 0; i <= db && !nonzero; i++)
    nonzero = zscompare(zb[i], 0l) != 0;
  zintoz(p, &zp);
  while (nonzero) {
    zpoly_div(*da, db, za, zb, zq, zr, &dq, &dr);
    for (i = 0; i <= dr; i++) {
      zcopy(zr[i], &zc);
      zmod(zc, zp, &zr[i]);
    }
    zero = 1;
    for (i = dr; i >= 0 && zero; i--) {
      zero = zscompare(zr[i], 0l) == 0;
      if (zero && dr > 0) dr--;
    }
    for (i = 0; i <= db; i++) zcopy(zb[i], &za[i]);
    *da = db;
    for (i = 0; i <= dr; i++) zcopy(zr[i], &zb[i]);
    db = dr;
    nonzero = 0;
    for (i = 0; i <= db && !nonzero; i++)
      nonzero = zscompare(zb[i], 0l) != 0;
  }
  if (*da > 0) {
    zinvmod(za[*da], zp, &zd);
    for (i = 0; i <= *da; i++) {
      zmulmod(za[i], zd, zp, &zc);
      zcopy(zc, &za[i]);
    }
  }
  zfree(&zc);
  zfree(&zd);
  zfree(&zp);
  for (i = 0; i < POLY_SIZE; i++) {
    zfree(&zb[i]);
    zfree(&zq[i]);
    zfree(&zr[i]);
  }
}

void zpoly_copy(long da, verylong *za, verylong *zb, long *db)
{
  long i;

  *db = da;
  for (i = 0; i <= da; i++) zcopy(za[i], &zb[i]);
}

void zpoly_print(long da, verylong *za)
{
  long i;

  for (i = da; i >= 0; i--) {
    zwrite(za[i]);
    printf(" ");
  }
  printf("\n");
}

void zpoly_ext_euclid(long dg, long dh, long p, verylong *zg,
                      verylong *zh, verylong *zs,
                      verylong *zt, verylong *zd,
                      long *ds, long *dt, long *dd)
{
  long da, dq, dr, ds1 = 0, ds2 = 0, dt1 = 0, dt2 = 0, i;
  verylong za[POLY_SIZE], zb[POLY_SIZE];
  verylong zq[POLY_SIZE], zr[POLY_SIZE];
  verylong zs1[POLY_SIZE], zs2[POLY_SIZE];
  verylong zt1[POLY_SIZE], zt2[POLY_SIZE];

  if (dh == 0 && zscompare(zh[0], 0l) == 0) {
    zpoly_copy(dg, zg, zd, dd);
    *ds = *dt = 0;
    zone(&zs[0]);
    zzero(&zt[0]);
  }
  for (i = 0; i < POLY_SIZE; i++) {
    za[i] = zb[i] = zq[i] = zr[i] = 0;
    zs1[i] = zs2[i] = zt1[i] = zt2[i] = 0;
  }
  zone(&zs2[0]);
  zzero(&zs1[0]);
  zzero(&zt2[0]);
  zone(&zt1[0]);
  while (dh != 0 || zscompare(zh[0], 0l) != 0) {
    zpoly_div(dg, dh, zg, zh, zq, zr, &dq, &dr);
    zpoly_mod(p, zq, &dq);
    zpoly_mod(p, zr, &dr);
    zpoly_mul(dq, ds1, zq, zs1, za, &da);
    zpoly_sub(ds2, da, zs2, za, zs, ds);
    zpoly_mul(dq, dt1, zq, zt1, za, &da);
    zpoly_sub(dt2, da, zt2, za, zt, dt);
    zpoly_mod(p, zs, ds);
    zpoly_mod(p, zt, dt);
    zpoly_copy(dh, zh, zg, &dg);
    zpoly_copy(dr, zr, zh, &dh);
    zpoly_copy(ds1, zs1, zs2, &ds2);
    zpoly_copy(*ds, zs, zs1, &ds1);
    zpoly_copy(dt1, zt1, zt2, &dt2);
    zpoly_copy(*dt, zt, zt1, &dt1);
    #ifdef DEBUG
    printf("q  = "); zpoly_print(dq, zq);
    printf("r  = "); zpoly_print(dr, zr);
    printf("s  = "); zpoly_print(*ds, zs);
    printf("t  = "); zpoly_print(*dt, zt);
    printf("g  = "); zpoly_print(dg, zg);
    printf("h  = "); zpoly_print(dh, zh);
    printf("s2 = "); zpoly_print(ds2, zs2);
    printf("s1 = "); zpoly_print(ds1, zs1);
    printf("t2 = "); zpoly_print(dt2, zt2);
    printf("t1 = "); zpoly_print(dt1, zt1);
    #endif
  }
  zpoly_copy(dg, zg, zd, dd);
  zpoly_copy(ds2, zs2, zs, ds);
  zpoly_copy(dt2, zt2, zt, dt);
  for (i = 0; i < POLY_SIZE; i++) {
    zfree(&za[i]);
    zfree(&zb[i]);
    zfree(&zq[i]);
    zfree(&zr[i]);
    zfree(&zs1[i]);
    zfree(&zs2[i]);
    zfree(&zt1[i]);
    zfree(&zt2[i]);
  }
}

void kernel(long m, long n, long p, verylong **zM,
            verylong **zX, long *r)
{
  int found;
  long *c = calloc(m, sizeof(long)), i, j, k, s;
  verylong zD = 0, za = 0, zb = 0, zp = 0;

  assert(c != 0);
  zintoz(p, &zp);
  *r = 0;
  for (i = 0; i < m; i++) c[i] = - 1;
  for (k = 0; k < m; k++) {
    found = 0, j = 0;
    while (!found && j < m) {
      found = zscompare(zM[k][j], 0l) != 0 && c[j] < 0;
      if (!found) j++;
    }
    if (found) {
      zinvmod(zM[k][j], zp, &zD);
      znegate(&zD);
      zintoz(- 1l, &zM[k][j]);
      for (s = k + 1; s < m; s++) {
        zmul(zD, zM[s][j], &za);
        zmod(za, zp, &zM[s][j]);
      }
      for (i = 0; i < n; i++) {
        if (i != j) {
          zcopy(zM[k][i], &zD);
          zzero(&zM[k][i]);
          for (s = k + 1; s < m; s++) {
            zmul(zD, zM[s][j], &za);
            zadd(zM[s][i], za, &zb);
            zmod(zb, zp, &zM[s][i]);
          }
        }
      }
      c[j] = k;
    }
    else {
      for (j = 0; j < n; j++) zzero(&zX[*r][j]);
      for (j = 0; j < n; j++) {
        for (s = 0; s < n; s++) {
          if (j == k) zone(&zX[*r][j]);
          else if (c[s] == j) zcopy(zM[k][s], &zX[*r][j]);
        }
      }
      *r = *r + 1;
    }
  }
  free(c);
  zfree(&zD);
  zfree(&za);
  zfree(&zb);
  zfree(&zp);
}

void Berlekamp_algorithm(long n, long p, verylong *zu,
                         verylong **zc, long *count)
{
  long da, db, dw, i, index = 0, j, k, s, r;
  verylong zd = 0, zn = 0, zp = 0;
  verylong za[POLY_SIZE], zb[POLY_SIZE];
  verylong zw[POLY_SIZE], zX[POLY_SIZE];
  verylong **zq = create_matrix(n, n), **zv = create_matrix(n, n);

  for (i = 0; i < POLY_SIZE; i++)
    za[i] = zb[i] = zw[i] = zX[i] = 0;
  zone(&zq[0][0]);
  zzero(&zX[0]);
  zone(&zX[1]);
  for (k = 1; k < n; k++) zzero(&zq[0][k]);
  zintoz(p, &zp);
  for (k = 1; k < n; k++) {
    zsmul(zp, k, &zn);
    zpoly_pow(1l, n, p, zn, zX, zu, za, &da);
    for (j = 0; j < n; j++)
      zcopy(za[j], &zq[k][j]);
  }
  #ifdef DEBUG
  printf("the Q-matrix is as follows:\n\n");
  for (i = 0; i < n; i++) {
    for (j = 0; j < n; j++) {
      zwrite(zq[i][j]);
      printf(" ");
    }
    printf("\n");
  }
  printf("\n");
  #endif
  for (i = 0; i < n; i++) {
    zsadd(zq[i][i], - 1l, &zd);
    zcopy(zd, &zq[i][i]);
  }
  kernel(n, n, p, zq, zv, &r);
  #ifdef DEBUG
  printf("the linearly independent vectors are as follows:\n\n");
  for (i = 0; i < r; i++) {
    for (j = 0; j < n; j++) {
      zwrite(zv[i][j]);
      printf(" ");
    }
    printf("\n");
  }
  printf("\n");
  #endif
  for (i = 0; i <= n; i++) zcopy(zu[i], &zw[i]);
  dw = n;
  *count = 0;
  for (i = 1; i < r; i++) {
    for (s = 0; s < p; s++) {
      for (j = 0; j < n; j++)
        zcopy(zv[i][j], &za[j]);
      zsadd(za[0], - s, &zd);
      zcopy(zd, &za[0]);
      da = n - 1;
      while (da > 0 && zscompare(za[da], 0l) == 0) da--;
      zpoly_gcd(da, dw, p, za, zw, zb, &db);
      if (db != 0) {
        for (j = 0; j <= db; j++)
          zcopy(zb[j], &zc[*count][j]);
        *count = *count + 1;
      }
    }
    for (j = 0; j < n; j++)
      zcopy(zc[index][j], &zw[j]);
    index++;
    dw = n - 1, j = dw;
    while (dw > 0)
      if (zscompare(zw[j--], 0l) == 0) dw--; else break;
  }
  delete_matrix(n, zq);
  delete_matrix(n, zv);
  zfree(&zd);
  zfree(&zn);
  zfree(&zp);
  for (i = 0; i < POLY_SIZE; i++) {
    zfree(&za[i]);
    zfree(&zb[i]);
    zfree(&zw[i]);
    zfree(&zX[i]);
  }
}

int main(void)
{
  long i, j, n = 8, p = 13l, r;
  verylong zu[POLY_SIZE];
  verylong **zX = create_matrix(8, 8);

  for (i = 0; i < POLY_SIZE; i++) zu[i] = 0;
  zone(&zu[8]);
  zone(&zu[6]);
  zintoz(10l, &zu[4]);
  zintoz(10l, &zu[3]);
  zintoz(8l, &zu[2]);
  zintoz(2l, &zu[1]);
  zintoz(8l, &zu[0]);
  printf("u = "); zpoly_print(n, zu);
  printf("\n");
  Berlekamp_algorithm(n, p, zu, zX, &r);
  printf("the linear independent polynomials are as follows:\n\n");
  for (i = 0; i < r; i++) {
    for (j = 0; j < n; j++) {
      zwrite(zX[i][j]);
      printf(" ");
    }
    printf("\n");
  }
  delete_matrix(8, zX);
  for (i = 0; i < POLY_SIZE; i++) zfree(&zu[i]);
  return 0;
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人性生交大片免费看中文网站| 欧美日韩一级二级| 91久久精品一区二区三区| 欧美高清激情brazzers| 国产三级三级三级精品8ⅰ区| 亚洲午夜一区二区三区| 国产大陆a不卡| 宅男在线国产精品| 日韩伦理免费电影| 国产精品一品视频| 日韩欧美国产综合一区| 亚洲男人的天堂在线aⅴ视频| 国产伦理精品不卡| 69av一区二区三区| 亚洲制服丝袜av| 成人激情小说乱人伦| 精品国产欧美一区二区| 亚洲制服丝袜av| 99久久精品国产导航| 日本一区二区三区电影| 精品一区二区三区蜜桃| 7777精品伊人久久久大香线蕉| 亚洲色图在线播放| 99久久久久免费精品国产| 久久久av毛片精品| 狠狠色丁香久久婷婷综合_中| 欧美日韩一区不卡| 亚洲高清视频的网址| 在线免费观看成人短视频| 成人免费在线观看入口| 成人黄动漫网站免费app| 国产性做久久久久久| 国产精品综合久久| 国产人成亚洲第一网站在线播放| 麻豆成人91精品二区三区| 91精品在线观看入口| 午夜精品久久久| 91精品国产一区二区三区| 天天色综合天天| 欧美一区二区二区| 久久国产尿小便嘘嘘| 亚洲精品一区二区三区四区高清| 老司机精品视频一区二区三区| 欧美一区二区国产| 韩国在线一区二区| 欧美国产日韩a欧美在线观看| 成人福利视频网站| 亚洲影院在线观看| 制服丝袜av成人在线看| 久久精品久久综合| 国产日韩欧美综合一区| 处破女av一区二区| 亚洲精品中文字幕乱码三区 | 一区二区三区久久久| 欧美影院一区二区三区| 天堂久久一区二区三区| 精品国产自在久精品国产| 国产高清不卡一区| 樱花影视一区二区| 日韩一级免费观看| 成人久久久精品乱码一区二区三区| 亚洲人成在线播放网站岛国| 欧美日韩国产一二三| 精品在线亚洲视频| 亚洲激情网站免费观看| 欧美高清视频www夜色资源网| 国产一区二区在线免费观看| 亚洲久草在线视频| 日韩一区二区精品| av色综合久久天堂av综合| 污片在线观看一区二区| 欧美精品一区二区三区很污很色的 | 一区二区在线观看不卡| 91精品国产色综合久久ai换脸| 久久91精品久久久久久秒播| 国产精品国产三级国产普通话99| 91福利在线播放| 精品一区二区免费| 一区二区国产盗摄色噜噜| 欧美变态tickling挠脚心| 色综合色综合色综合色综合色综合 | 懂色av一区二区三区免费观看 | 亚洲天堂成人网| 欧美成人精品二区三区99精品| caoporn国产精品| 蜜桃视频在线一区| 亚洲国产一区二区视频| 国产精品色婷婷久久58| 日韩欧美亚洲一区二区| 91亚洲国产成人精品一区二区三 | 日产国产欧美视频一区精品| 中文字幕电影一区| 久久影院午夜片一区| 欧美自拍丝袜亚洲| a4yy欧美一区二区三区| 国产一区二区在线观看视频| 婷婷丁香激情综合| 亚洲美女电影在线| 国产精品久久久久久福利一牛影视| 91精品国产麻豆国产自产在线| 97久久人人超碰| 国产.欧美.日韩| 国产精品一区二区三区99| 婷婷久久综合九色综合绿巨人| 亚洲卡通欧美制服中文| 中文字幕制服丝袜成人av| 国产午夜亚洲精品午夜鲁丝片| 欧美一级欧美一级在线播放| 欧美三级视频在线| 91福利在线播放| 在线观看网站黄不卡| 99精品视频在线观看| 成人aaaa免费全部观看| 成人网页在线观看| caoporn国产精品| 91亚洲大成网污www| 91免费视频观看| 在线免费不卡视频| 在线视频中文字幕一区二区| 欧美综合色免费| 欧美日韩国产综合视频在线观看| 欧美三级电影在线看| 欧美日韩在线综合| 91精品欧美福利在线观看| 91精品免费观看| 欧美成人午夜电影| 国产三级精品三级| 中文字幕一区不卡| 亚洲一二三四久久| 琪琪一区二区三区| 国产一区二区三区免费观看| 国产精品1区二区.| 95精品视频在线| 看片的网站亚洲| 成人免费精品视频| 色88888久久久久久影院按摩| 欧美性生活久久| 欧美一区二区福利在线| 久久久久97国产精华液好用吗| 中文字幕不卡三区| 亚洲一区二区三区在线| 蜜乳av一区二区| 国产91精品露脸国语对白| 91小视频免费看| 91麻豆精品国产91久久久| 久久精品人人爽人人爽| 亚洲精品视频一区| 美女一区二区视频| 成人毛片视频在线观看| 欧美色图激情小说| 国产亚洲人成网站| 亚洲国产毛片aaaaa无费看| 麻豆成人久久精品二区三区红| 成人久久18免费网站麻豆| 欧美网站一区二区| 欧美精品一区二区三区四区 | 中日韩免费视频中文字幕| 亚洲欧美另类小说| 久久99国产精品麻豆| 97se狠狠狠综合亚洲狠狠| 欧美一级在线观看| 一区二区三区四区精品在线视频| 久热成人在线视频| 欧美在线一区二区| 国产精品三级av| 美女网站一区二区| 在线免费av一区| 国产精品毛片久久久久久久| 蜜臀av性久久久久蜜臀aⅴ流畅 | 色婷婷精品大在线视频| 久久一区二区三区四区| 亚洲乱码一区二区三区在线观看| 日本免费在线视频不卡一不卡二| 99久精品国产| 国产女人水真多18毛片18精品视频| 亚洲成人动漫精品| av在线不卡免费看| 久久精品欧美日韩| 麻豆精品一区二区综合av| 欧美在线播放高清精品| 中文字幕在线一区二区三区| 国产一区二区三区免费在线观看| 欧美日韩精品一区二区天天拍小说| 国产精品对白交换视频| 国产成人综合在线| 欧美精品一区二区三区在线 | av一区二区三区| 久久精品一区四区| 黄色成人免费在线| 精品国产制服丝袜高跟| 亚洲国产裸拍裸体视频在线观看乱了 | 中文字幕在线观看一区二区| 国产精品一区专区| 国产亚洲欧洲一区高清在线观看| 老司机一区二区| 日韩精品一区二区三区中文精品| 亚洲123区在线观看| 欧美日韩国产天堂| 亚洲超碰精品一区二区| 欧美日韩另类一区|