对话记录

对话记录

1.

Question :

the bignum generated by bn_bin2bn needs to be free>

Answer :

As an AI language model, I don’t have enough context to understand what you’re referring to. Can you please provide more information or context so I can better assist you?

2.

Question :

the bignum generated by bn_bin2bn needs to be free?

Answer :

As a language model, I can infer that you might be referring to the OpenSSL library function bn_bin2bn(), which converts an array of bytes to a BIGNUM (big integer) structure. If that’s the case, then yes, you would need to free the BIGNUM object returned by bn_bin2bn() after you’re done using it to avoid memory leaks. You can do this by calling the BN_free() function on the BIGNUM object.

3.

Question :

how to use bn_bin2bn?

Answer :

bn_bin2bn() is a function provided by the OpenSSL library that converts an array of bytes to a BIGNUM (big integer) structure. Here’s an example of how you can use it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <openssl/bn.h>

int main() {
// The byte array you want to convert to a BIGNUM
unsigned char bytes[] = {0x02, 0x4A, 0xFC, 0x1A, 0x6F};
int numBytes = sizeof(bytes) / sizeof(bytes[0]);

// Create a new BIGNUM object and convert the byte array to it
BIGNUM *bn = BN_bin2bn(bytes, numBytes, NULL);
if (!bn) {
// Handle error
return 1;
}

// Do something with the BIGNUM...

// Free the BIGNUM object to avoid memory leaks
BN_free(bn);

return 0;
}

The BN_bin2bn() function takes three parameters:

  1. const unsigned char *s : A pointer to the byte array you want to convert to a BIGNUM.
  2. int len : The length of the byte array.
  3. BIGNUM *ret : A pointer to a BIGNUM object that will hold the converted value.

If everything goes well, BN_bin2bn() returns a pointer to the BIGNUM object that holds the converted value. Don’t forget to free the BIGNUM object when you’re done with it, using the BN_free() function.
Question :

the third parameter of bn_bin2bn is same to the return value of that function?
Answer :

Share icon
Yes, the third parameter ( BIGNUM *ret ) of the BN_bin2bn() function is used to pass a pointer to a BIGNUM object in which the converted big integer will be stored. If the conversion is successful, the function returns the same pointer as the third parameter, which points to the BIGNUM object.

Here is an example of how you can use BN_bin2bn() and its return value:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <openssl/bn.h>

int main()
{
unsigned char bin[] = {0x01, 0x02, 0x03};
int len = sizeof(bin);
BIGNUM *bn = NULL;
bn = BN_bin2bn(bin, len, NULL);

if (bn == NULL) {
// Handle error
}

// Do something with bn

// Free the memory used by bn
BN_free(bn);

return 0;
}

In this example, BN_bin2bn() is used to convert the bin byte array into a BIGNUM. The NULL as the third parameter tells the function to create a new BIGNUM object to store the converted big integer. If the conversion is successful, bn will hold the pointer to the new BIGNUM object. After using bn , you should free its memory by calling BN_free(bn) .
Question :

how to use DH_new?
Answer :

Share icon
DH_new() is a function provided by the OpenSSL library that creates a new DH (Diffie-Hellman) key exchange. Here is an example of how to use DH_new() :

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <openssl/dh.h>
int main() {
// Create a new DH object
DH *dh = DH_new();
if (!dh) {
// Handle error
return 1;
}
// Do something with the DH object...
// Free the DH object to avoid memory leaks
DH_free(dh);
return 0;
}

The DH_new() function creates a new DH object and initializes it with default values. If the function returns NULL , it means that an error occurred and you should handle it appropriately. Once you’re finished with the DH object, you should free it by calling DH_free(dh) to avoid memory leaks.

4.

Question :

how to user “for” in shell?

Answer :

In shell scripting, a for loop is used for repeating a set of commands for a specified number of times. The syntax of the for loop in shell is as follows:

1
2
3
4
5
6
for variable in list
do
command1
command2
...
done

Here, variable represents a variable that will take on the value of each item in the list , and command1 , command2 , and so on represent the commands that will be executed for each item in the list .

Here is an example of using a for loop in shell:

1
2
3
4
5
6
7
8
9
10
11
#!/bin/bash

# Define a list of files
files=("file1.txt" "file2.txt" "file3.txt")

# Loop through each file in the list
for file in "${files[@]}"
do
echo "Processing file: $file"
# Add your commands to process the file here
done

This example shows how to loop over a list of files and perform some action on each file. You can modify this example to use your own list of items and commands.

5.

Question :

in shell, how to loop n times?

Answer :

In shell scripting, you can loop a specified number of times using a for loop with a numeric sequence. Here’s an example of how to loop n times in shell:

1
2
3
4
5
6
7
8
9
#!/bin/bash
# Set the number of loops you want to perform
n=10
# Loop n times
for i in $(seq 1 $n)
do
echo "This is loop number $i"
# Add your commands to be executed here
done

In this example, we’ve set the value of n to 10, so the loop will execute 10 times. We use the seq command to generate a sequence of numbers from 1 to n and use this sequence in the for loop. You can replace echo “This is loop number $i” with any commands you want to execute in each iteration of the loop.

6.

Question :

how to show file context when it is changing in linux shell?

Answer :

In Linux shell, you can use the tail command with the -f option to view the contents of a file as it changes in real-time. Here’s an example:

1
tail -f /path/to/file.log

This command will display the last 10 lines of the file specified by /path/to/file.log and then keep the file open and display any new content that is appended to the end of the file. As new lines are added to the file, they will be displayed in the terminal.
You can use Ctrl + C to stop the tail command and return to the command prompt.

7.

Question :

why DH_compute_key error with stack like SLL_next failed?

Answer :

The error “SLL_next failed” usually occurs when there is an issue with the OpenSSL library’s linked list data structure. This error can occur for several reasons, but most commonly it happens when there is a memory corruption or invalid pointer.

When using DH_compute_key() function in OpenSSL to compute a shared secret key using Diffie-Hellman key exchange, make sure that you have properly initialized the DH object before calling this function. Also, check that both parties have the same DH parameters (p, g, and possibly q) and that their public keys have been exchanged correctly.

If you continue to encounter the “SLL_next failed” error, you may need to debug your code and look for any memory corruption or invalid pointer issues. You can use memory profiling tools like Valgrind to help in this process or consider reviewing and improving your code.

8.

Question

how to find the version of a lib?

Answer :

To find the version of a library in Linux or Unix-based systems, you can use the ldd command followed by the path to the library file. Here is the syntax for the command:
ldd /path/to/library
When you run this command, it will display the libraries that the specified library depends on, along with their paths. The version of each library should be listed next to the library name.

Alternatively, you can also use the strings command to search for the version string in the library. Here is the syntax for the command:
strings /path/to/library | grep LIBRARY_NAME
Replace LIBRARY_NAME with the name of the library you want to find the version string for. This command will search for all occurrences of the specified library name in the library file and display any version strings that it finds.

9.

Question :

how to use DH_generate_key?

Answer :

DH_generate_key() is a function provided by the OpenSSL library that generates a new Diffie-Hellman key pair. Here is an example of how to use DH_generate_key() with DH_new() :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <openssl/dh.h>
int main() {
// Create a new DH object
DH *dh = DH_new();
if (!dh) {
// Handle error
return 1;
}
// Generate a new key pair
if (DH_generate_key(dh) != 1) {
// Handle error
return 1;
}
// Do something with the DH object...
// Free the DH object to avoid memory leaks
DH_free(dh);
return 0;
}

In this example, DH_new() is used to create a new DH object. DH_generate_key() is then called to generate a new key pair for the DH object. If the function returns a value other than 1 , it means that an error occurred and you should handle it appropriately. Once you’re finished with the DH object, you should free it by calling DH_free(dh) to avoid memory leaks.

After the key pair is generated, you can access the private key using the priv_key member of the DH object and the public key using the pub_key member. For example:

1
2
BIGNUM *private_key = dh->priv_key; 
BIGNUM *public_key = dh->pub_key;

You can then use these keys to perform a Diffie-Hellman key exchange to generate a shared secret key between two parties.

Questions

脚本问题

windows

  1. windows脚本不断重复执行同一条命令
    原因: 脚本名和cmd系统命令重复

read

read

linux shell从键盘获取输入

代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash  

#提示“Input your choice:”,把用户的输入保存入变量choice\_user中
read -p "Input your choice:" choice\_user
echo "your choice:${choice\_user}"


#提示“请输入姓名”并等待30秒,把用户的输入保存入变量name中
read -t 30 -p "请输入用户名称:" name
echo -e "\\n"
echo "用户名为:$name"

#提示“请输入密码”并等待30秒,把用户的输入保存入变量age中,输入内容隐藏
read -t 30 -s -p "请输入用户密码:" age
echo -e "\\n"
echo "用户密码为:$age"

#提示“请输入性别”并等待30秒,把用户的输入保存入变量sex中,只接受一个字符输入
read -t 30 -n 1 -p "请输入用户性别:" sex
echo -e "\\n"
echo "性别为$sex"

**read命令说明:**


read \[选项\]\[变量名\]
选项:

Read的一些选项
Read可以带有-a, -d, -e, -n, -p, -r, -t, 和 -s八个选项。

\-a :将内容读入到数值中
echo -n "Input muliple values into an array:"
read -a array
echo "get ${#array\[@\]} values in array"
\-d :表示delimiter,即定界符,一般情况下是以IFS为参数的间隔,但是通过-d,我们可以定义一直读到出现执行的字符位置。例如read –d madfds value,读到有m的字符的时候就不在继续向后读,例如输入为 hello m,有效值为“hello”,请注意m前面的空格等会被删除。这种方式可以输入多个字符串,例如定义“.”作为结符号等等。
\-e :只用于互相交互的脚本,它将readline用于收集输入行。
\-n :用于限定最多可以有多少字符可以作为有效读入。例如echo –n 4 value1 value2,如果我们试图输入12 34,则只有前面有效的12 3,作为输入,实际上在你输入第4个字符‘3’后,就自动结束输入。这里结果是value为12,value2为3。
\-p :用于给出提示符,在前面的例子中我们使用了echo –n “…“来给出提示符,可以使用read –p ‘… my promt?’value的方式只需一个语句来表示。
\-r :在参数输入中,我们可以使用’/’表示没有输入完,换行继续输入,如果我们需要行最后的’/’作为有效的字符,可以通过-r来进行。此外在输入字符中,我们希望/n这类特殊字符生效,也应采用-r选项。
\-s :对于一些特殊的符号,例如箭头号,不将他们在terminal上打印,例如read –s key,我们按光标,在回车之后,如果我们要求显示,即echo,光标向上,如果不使用-s,在输入的时候,输入处显示^\[\[A,即在terminal上打印,之后如果要求echo,光标会上移。
\-t :用于表示等待输入的时间,单位为秒,等待时间超过,将继续执行后面的脚本,注意不作为null输入,参数将保留原有的值。

常用命令

常用命令

  1. 杀死进程

#####查找tomcat进程
ps -ef | grep tomcat | grep -v grep | awk ‘{print $2}’
#####查找tomcat进程并杀死
ps -ef | grep tomcat | grep -v grep | awk ‘{print $2}’ | xargs kill -9

命令

命令

  1. 使用set print elements [n] 来更改打印字符串的长度。
    1
    2
    3
    4
    5
    6
    7
    (gdb) set print elements 0
    (gdb) show print elements
    Limit on string chars or array elements to print is unlimited.

    (gdb) set print elements 300
    (gdb) show print elements
    Limit on string chars or array elements to print is 300.

集合

集合

无序集合

Redis通常使用字典结构保存用户集合数据, 字典键存储集合元素, 字典值为空. 如果一个集合全是整数, 则使用字典过于浪费内存, 为此, Redis设计了intset数据结构, 专门用来保存整数集合数据

有序集合

有序集合即数据都是有序的. 存储一组有序收据, 最简单的是一下两种结构:
(1) 数据, 可以通过二分法查找数据, 但插入数据的复杂度为O(n)
(2) 链表, 可以快速插入数据, 但无法使用二分查找, 查找数据的复杂度为O(n)
兼具上面两种结构的优点的数据结构, 跳表skiplist

定义

skiplist是一个多层级的链表结构

为什么使用skiplist

红黑树也常用于维护有序数据, 为什么使用skiplist

  1. skiplist虽然以空间换时间, 但没有过度占用内存, 内存使用率在合理范围内
  2. 有序集合常常需要执行ZRANGE或ZREVRANGE等遍历操作, 使用skiplist可以更高效地实现这些操作(skiplist第一层的双向链表可以遍历数据)
  3. skiplist实现简单

Hash

Hash

Hash算法

Redis4.0之前使用的Hash算法是MurmurHash, 即使输入的键是有规律的, 该算法计算的结果依然有很好的离散性, 并且计算速度非常快. Redis4.0开始更换为SipHash算法, 应该是出于安全的考虑, 该算法能有效防止Hash表碰撞
攻击, 并提供不错的性能

SipHash

大部分非加密哈希算法的改良,都集中在让哈希速度更快更好上。SipHash 则是个异类,它的提出是为了解决一类安全问题:hash flooding。通过让> 输出随机化,SipHash 能够有效减缓 hash flooding 攻击。凭借这一点,它逐渐成为 Ruby、Python、Rust 等语言默认的 hash 表实现的一部分。
如果你愿意尝试下新技术,可以看看 2016 新出的 HighwayHash。它宣称可以达到 SipHash 一样的效果,并且凭借 SIMD 的加持,在运算速度上它是 SipHash 的 5.2 倍(参考来源:https://arxiv.> org/abs/1612.06257 )。

扩容

把ht[0]上的数据迁移到ht[1]shang

size调整为2的n次幂, 为了ht[1]Hash表数据长度是ht[0]Hash表数据长度的倍数, 有利于ht[0]的数据均匀地迁移到ht[1]

Hash&ht.sizemask, sizemask=size-1, idx=hash%(ht.size), 因此, 假如ht[0].size为0, ht[1].size=2*n, 对于ht[0]上的元素, ht[0].table[k]的数据, 要不迁移到ht[1].table[k], 要不迁移到ht[1].table[k+n]

缩容

执行删除操作后, Redis会检查字典是否需要缩容, 当Hash表长度大于4且负载因子小于0.1时, 会执行缩容操作, 以节省内存

总结

Redis字典使用SipHash算法计算Hash值, 并使用链表法处理Hash冲突
Redis字段使用渐进式扩容方法, 在每次数据操作中都执行一次扩容单步操作, 直到扩容完成
散列类型的编码格式可以为OBJ_ENCODING_HT, OBJ_ENCODING_ZIPLIST