const 发布的文章

“const”

nlohmann json 将键值从字符串修改为数组
如下,原数据是这样
j["example"]="hello example";
修改成
j["example"]=json({"example2", "hello example2"});

好像直接这样就可以了.

测试验证

json j;
j["example"] = "hello example";
cout << j.dump(4) << endl;
j["example"] = json({"example2", "hello example2"});
cout << j.dump(4) << endl;

结果

{
    "example": "hello example"
}
{
    "example": [
        "example2",
        "hello example2"
    ]
}

测试代码

json j;
j["example"] = "hello example";
cout << j.dump(4) << endl;
j["example"] = json::array();
json j1, j2;
j1["one"] = 1;
j2["two"] = 2;
j["example"].push_back(j1);
j["example"].push_back(j2);
cout << j.dump(4) << endl;

运行结果:

{
    "example": "hello example"
}
{
    "example": [
        {
            "one": 1
        },
        {
            "two": 2
        }
    ]
}

证券时报记者 余胜良

  近期有烂尾楼盘业主集体决定停止还贷,引得不少烂尾楼盘业主效仿。如果这股风潮蔓延开来,有可能对楼市造成负面冲击,对楼盘销售更为不利,也不利于金融系统稳定。

  如果是没有出售的烂尾楼,还不涉及购房者,只涉及开发商、银行、其他资金提供方、施工方和供应商,但是因为我国实现预售制度,烂尾楼盘很多已经销售完毕,或者某一期销售完毕,业主在付出真金白银后,面临楼盘无法交付的压力。由于大多数业主是贷款买房,每月还要支付月供。随着期房停工时间延长,日益接近交付日期,业主发现楼盘无法按时交付,心态越发不稳,有动力维护自身权益。

  楼盘已经销售,正常情况下,房地产维持一定的毛利率,只要不是被各种财务成本拖垮,按时交付还有一定利润,开发商有动力促使楼盘交付。楼盘面临无力支付工程款的情况,绝大多数是房产公司旗下项目公司资金被转走,房产公司以项目公司出资为整个楼盘风险负责,真出事后,往往无法覆盖风险。业主只能迁怒项目监管方,凭什么银行可以继续收利息,期房业主却要面临房产烂尾的风险,而当初交上去的资金,为何没有做到好好监管,任凭项目方挪用?

  开发楼盘是长周期项目,企业需要大量资金做周转,预售也有一定合理性。

  项目方挪用资金,是房企的惯用手段,房企有一个特色,做大的公司往往要高周转,在拿地、建房、回款、还债这个循环中,回款是关键一环,让整个循环持续转动下去,但是因为是高杠杆,在房地产压缩杠杆的大背景下,没有新钱进来,房企资金链断裂,导致多地出现烂尾楼。

  应该明确一点,在这个循环中,最无辜的就是业主,业主主动要求强制停供,也是走投无路,其本心还是希望问题得到解决,能够早日成为真正的业主。如果问题得不到解决,受伤害的不仅是业主,他们可能面临征信污点,还有整个楼市,楼市在危机持续下,买房者会更加谨慎,还有金融机构,金融机构尽管有房产做抵押,但是没有交付的房产,只能成为坏账,当坏账增加,还可能造成系统性金融风险。

  让烂尾楼活起来,早日交付才有利于千家万户的稳定,各地政府应该研究如何盘活烂尾楼,把死棋下活,追讨转移走的资金,或者引入有实力的房企,将保交付放在优先位置。

https://finance.sina.com.cn/review/jcgc/2022-07-13/doc-imizirav3120012.shtml

近期有两组数据,让人有一种感受:中国老百姓更爱存钱了。

上半年住户存款增加超10万亿元

央行11日发布的数据显示,上半年人民币存款增加18.82万亿元,同比多增4.77万亿元。其中,住户存款增加10.33万亿元,非金融企业存款增加5.3万亿元,财政性存款增加5061亿元,非银行业金融机构存款增加9513亿元。6月份,人民币存款增加4.83万亿元,同比多增9741亿元。

上半年住户存款增加10.33万亿元,这是什么概念?这意味着,在上半年,平均每天约571亿存款涌向银行。

纵向来看,2021年上半年住户存款增加7.45万亿元,2020年上半年住户存款增加8.33万亿元,2019年上半年住户存款增加6.82万亿元,2018年上半年住户存款增加4.26万亿元。也就是说,2022年上半年增加的住户存款创出近年同期的新高。

58.3%居民倾向于“更多储蓄”

根据央行发布的2022年第二季度城镇储户问卷调查报告,倾向于“更多消费”的居民占23.8%,比上季增加0.1个百分点;倾向于“更多储蓄”的居民占58.3%,比上季增加3.6个百分点;倾向于“更多投资”的居民占17.9%,比上季减少3.7个百分点。

也就是说,愿意更多存钱的人大幅变多了,而愿意更多投资的人变少了。

上半年住户存款大幅增长,还有未来储蓄意愿的提升,令小伙伴们心生疑问:为什么大家更爱存钱了?

中国人更爱存钱的背后

招联金融首席研究员董希淼对中新网“中国新观察”栏目表示,居民存款大幅度增长、储蓄意愿增强的原因是多方面的,既有短期影响也有长期因素。

董希淼指出,从短期因素看,主要是新冠肺炎疫情带来的冲击。今年3月份以来,我国疫情持多点散发,部分企业难以正常生产经营,不稳定、不确定因素增多,导致居民预防性储蓄动机上升。

与此同时,今年以来受国际金融市场震荡影响,我国资本市场波动加剧,股票、基金收益明显下降,特别是银行理财产品出现“破净”,导致居民风险偏好有所下降,部分资金重新流向存款。

兴业银行首席经济学家鲁政委在研报中表示,2020年的经验显示,疫情会导致居民存款同比增速上升,而且存款同比增速会在较高水平上保持一段时间。

董希淼认为,作为消费主力军的中青年群体,除了收入上具有优势以外,还面临“上有老、下有小”等生活压力。居民对未来收入和支出的不确定性预期提高,使得居民预防意识和储蓄意愿明显增强。此外,随着房地产市场调控力度加大,居民住房消费意愿持续不振,减少了住房消费支出,部分转为居民存款。

怎样才能刺激消费?

储蓄变多,有利有弊。

董希淼表示,居民存款持续增加提高我国经济发展韧性,增强居民部门抵御风险能力,但也反映出居民对未来预期转弱、消费需求不足、投资意愿下降等问题。下一步,应采取针对性的措施,稳住居民预期和信心,进一步提振居民消费和投资。

他建议,严格落实国家卫健委“九不准”要求,平衡好疫情防控和经济增长的关系,最大限度降低疫情防控对经济和民生的冲击,稳定企业和居民的预期。进一步稳住宏观经济大盘。落实好前期出台的稳经济一系列政策措施,财政政策和货币政策应更加积极有为,主动发力,继续助力市场主体纾困解难和实体经济稳步恢复,稳定居民就业,提高居民收入。

董希淼指出,要提振居民消费意愿和能力。持续释放国内市场潜力,采取积极有效措施,改变居民消费动机不足等问题,改善居民消费环境,培育中高端消费增长点,扩大汽车等耐用消费品消费,促进居民消费转型升级。进一步落实好差别化的住房信贷政策,合理把握信贷投放,更好地满足居民自住型和改善型购房需求。

从长远看,董希淼建议,进一步完善全覆盖的社会保障体系,更好地满足居民养老、就医、教育等方面的迫切需求,降低居民后顾之忧进而降低预防性储蓄意愿。

当前,各地也在想方设法来刺激消费,提振汽车和房地产消费成为重要抓手。

在促进汽车消费方面,除了减征购置税外,多地还拿出真金白银的补贴,刺激大家买车。在刺激房地产消费方面,多地已经宣布放松限购、限售,降低首付比例,相当多的城市还会发放购房补贴。另外,多地也通过发放消费券来拉动消费,比如北京7月起线上线下发放1亿元餐饮消费券。(记者 李金磊)

使用openssl 生成rsa-pss 密钥

openssl genpkey -algorithm rsa-pss          \
    -pkeyopt rsa_keygen_bits:2048           \
    -pkeyopt rsa_pss_keygen_md:sha256       \
    -pkeyopt rsa_pss_keygen_mgf1_md:sha256  \
    -pkeyopt rsa_pss_keygen_saltlen:32      \
    -out rsa-pss-privateKey.pem

cat rsa-pss-privateKey.pem

-----BEGIN PRIVATE KEY-----
MIIE7gIBADA9BgkqhkiG9w0BAQowMKANMAsGCWCGSAFlAwQCAaEaMBgGCSqGSIb3
DQEBCDALBglghkgBZQMEAgGiAwIBIASCBKgwggSkAgEAAoIBAQCVDnc3tuB3do2g
I2V08eEAMF1pJd5nUJ6SYnBOqKEQ2ZNsU6OV51WGx3leN9gjEdkKjErUi8N0YMo9
TMK0cXpZzHmn/lU6HY3qe/i5ZGhSWWPtC1jE6Tt1BgnfXR9jc9S/+lxfZm9UFSsc
JMwBivbvPEXIyauWA3ww7A7oDh6oC4J5u7clgfbzRGJKLBD2raEMmnTVJoiVTshn
9Wyrm+B/mJK2YhG5pxAQ7pwaK6/eMDn1hLWAJIIS5USz50AC04T9fpenz14ITiWd
9lbKOVBzjHmo67UnhhrNoB8Kf8W6Ti4XEOBwdg/Kaa4hFofk8mV2ymJYYZ6scHbd
2pFcJQWlAgMBAAECggEAded7ZhbCd7zPSly1ZEvwLrYTLZlG03Jx/FjhfVbmEO4K
LyX5wBm9DV+8IUsLLLJxfGZ8yqPDd8sYLmUJnrIkleOoV7pWsCGwoEpv9DX4Tytm
X5saHKhg37BnHsgKjCCTqUfgyZW9ekVEVH7G4HGL4rFKggkEMSWQlyIiqGyC02kS
PEdPcMuBx1AKHWVjtQLc5E4v2lYmhlqVX1N97XcNrbNRdTjOpL4eyf6zkb0IJjuu
9FZYVIDjRe+HI0xMUxTobJXuP5amL9upegCF5hiL0oxUM7kK/UVwPK+SjtV0T3sC
BImxfCAefzOX9K7IGbtECSDPxh+UEIYXv2p+YwEQAQKBgQDF2vcU75Rbv4hgy/iP
16n7XfzZ0+kmfoxetiMM6s/LX3kv85KFyu3+Zm4NZG9gATjs412GoP4YcHzfF9O5
pRNAMaGxBAVzDUG0QGxuwqBPImkKhPBHp46R19UzBuoOKD2N6U3ko0sv567H0+wJ
10dknIn3urNCSeJiTYouxL3y+QKBgQDA3EWGHwod9B7X3brEoBaFkVOM5gemh+ZO
OngnzsH+MDx3a4fIyLvlYQh4gVjx0oR4ctaHJ2acfBKu1xTetIAiBgYrv5Ov2Of4
1/VdF+HEG0pu0wISNZ08dzdAaDT9jRctI5caHQqBjFv4bvMzG466WhHVkH0+cFT+
GNYVuYnnDQKBgENWp9tPQv4K7P6MzTcfnnG35lO4xNReI6YkdT9zN2+vOc6xJoA0
tdVsxS33rdRN9jLhmzYz2uc0ebtwH5ZCcY/alH5rsPMcYu1XM9Bqmybzvi5fWmv4
whQvEhfA1a4l0fVXnzQew3s1bg4CuYYL5/d9M5PFzjbUcKEmZM5QFZn5AoGBAK+7
xuoIfIqAuF4Qn6+tA/ifTJd1v4DiElwz8Oqs/p2kzGQwqmCtcHD5suNDUY3AOo8a
bRpoL5rlf4yrVUv9A0h9XsAcZ/Fy3yUje2NhcInmKDPFt/xpuCWxp7nbenWTS4wJ
AxV7Yuhawi8kwhxOvwZVLi0A5O6xIvEKJoFTODI9AoGBAIF9u17oUZK59dnxA1v1
kv06VvC8JxB95lbc5FlK8ZOeNxxvPf6Y2DqbtkmK8Mc2gfTFH1e6+i6Qr0AE5MBC
2icqlbWAyCbuwlLr9cvbG8Pp/qTrs4dTXWVE4+JRaYytpEt/0395ohAjH+9uvfxr
WuP6176mGPZ4FF1/cIqesl/N
-----END PRIVATE KEY-----

openssl rsa -in rsa-pss-privateKey.pem -pubout -out rsa-pss-publicKey.pem

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlQ53N7bgd3aNoCNldPHh
ADBdaSXeZ1CekmJwTqihENmTbFOjledVhsd5XjfYIxHZCoxK1IvDdGDKPUzCtHF6
Wcx5p/5VOh2N6nv4uWRoUllj7QtYxOk7dQYJ310fY3PUv/pcX2ZvVBUrHCTMAYr2
7zxFyMmrlgN8MOwO6A4eqAuCebu3JYH280RiSiwQ9q2hDJp01SaIlU7IZ/Vsq5vg
f5iStmIRuacQEO6cGiuv3jA59YS1gCSCEuVEs+dAAtOE/X6Xp89eCE4lnfZWyjlQ
c4x5qOu1J4YazaAfCn/Fuk4uFxDgcHYPymmuIRaH5PJldspiWGGerHB23dqRXCUF
pQIDAQAB
-----END PUBLIC KEY-----

echo -n "hello world" > tbs.txt
openssl dgst -sha256 -sign rsa-pss-privateKey.pem -out tbs.sign tbs.txt 
hexdump -C tbs.sign 

00000000 10 34 d7 ae 8d 29 b3 bb 81 b1 24 f8 e7 b5 55 95 |.4...)....$...U.|
00000010 8c 60 4b 70 1d 66 c8 e1 99 8a cb 7c 77 e9 dd 6e |.`Kp.f.....|w..n|
00000020 39 8c b7 91 1d a0 a3 f6 2c ef ee 1d 9f 4c e1 ae |9.......,....L..|
00000030 4c 78 10 37 cb aa 11 c8 cd 2a f7 a4 91 8a 6c 83 |Lx.7.....*....l.|
00000040 2c 32 fa 37 42 71 1d 5a bc 8d 2c d2 54 74 38 f5 |,2.7Bq.Z..,.Tt8.|
00000050 ca 33 a3 e9 54 f2 1b a2 72 71 9f 3c aa 7c c2 1c |.3..T...rq.<.|..|
00000060 e8 33 9f f8 a6 9a 9d ac f5 c4 cb e6 a9 da 66 7b |.3............f{|
00000070 6f f2 a9 cf 6b 9f 91 d8 f7 3d ec 74 f0 77 76 07 |o...k....=.t.wv.|
00000080 ec 60 32 bd cf 7f 22 f1 94 66 be 03 c3 1b 8d b3 |.`2..."..f......|
00000090 8c 21 a9 da d1 72 3c a0 f0 91 1d ae 05 18 13 ab |.!...r<.........|
000000a0 e6 3e c0 44 ea b6 43 f5 e2 8d 57 a7 8a 1d e3 75 |.>.D..C...W....u|
000000b0 bd b1 0e aa 4e b9 16 a9 56 67 4c 11 75 da b2 08 |....N...VgL.u...|
000000c0 bc bc 9a 1a 98 60 2b cc 51 6a b8 4d 2d 07 5c 61 |.....`+.Qj.M-.a|
000000d0 c3 89 00 a4 0a cd aa 17 50 ac 2a 3c 4d 28 3b 8d |........P.*<M(;.|
000000e0 32 29 75 f9 d6 79 72 34 f4 07 db 9f 42 25 ef 7a |2)u..yr4....B%.z|
000000f0 9c d2 b0 24 fd e0 91 d9 be 02 d3 ae da 38 28 f8 |...$.........8(.|

openssl dgst -sha256 -verify rsa-pss-publicKey.pem  -signature  tbs.sign -sigopt rsa_padding_mode:pss tbs.txt 

Verified OK

使用不带pkeyopt的rsa密钥实现rsa-pss签名与验签时,使用

openssl dgst -sign [private_key_file] -sha256 -sigopt rsa_padding_mode:pss -out [output_file] [input_file]
openssl dgst -verify [public_key_file] -signature [signature_file] -sigopt rsa_padding_mode:pss [signature_message_file]

参考:https://linuxcommandlibrary.com/man/openssl-dgst

使用openssl pkeyutl 签名验签

openssl dgst -sha256 -binary -out tbs.sha256 tbs.txt
openssl pkeyutl -sign \
  -in tbs.sha256 -inkey rsa-pss-privateKey.pem \
  -out tbs.sign \
  -pkeyopt digest:sha256 \
  -pkeyopt rsa_padding_mode:pss \
  -pkeyopt rsa_pss_saltlen:-1

  openssl pkeyutl -verify \
  -in tbs.sha256 -sigfile tbs.sign \
  -pkeyopt rsa_padding_mode:pss \
  -pubin -inkey rsa-pss-publicKey.pem \
  -pkeyopt rsa_pss_saltlen:-1 \
  -pkeyopt digest:sha256

Signature Verified Successfully

GO 读取带pkeyopt的密钥

func pem_to_pri(pripem string) *rsa.PrivateKey {

    block, _ := pem.Decode([]byte(pripem))
    if block == nil || (block.Type != "PRIVATE KEY" && block.Type != "RSA PRIVATE KEY") {
        log.Fatal("failed to decode PEM", block)
        return nil
    }
    var oidPrivateKeyRsaPss = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
    type pkcs8 struct {
        Version    int
        Algo       pkix.AlgorithmIdentifier
        PrivateKey []byte
    }
    var privKey pkcs8
    if _, err := asn1.Unmarshal(block.Bytes, &privKey); err != nil {
        return nil
    }

    if privKey.Algo.Algorithm.Equal(oidPrivateKeyRsaPss) {
        rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKey.PrivateKey)
        if err == nil {
            return rsaPrivKey
        }
    }
    rsaPrivKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)

    if err != nil {
        log.Println(err)
        return nil
    }

    return rsaPrivKey
}

parsing the rsa pss key manually

func loadPrivateKey(pemEncodedPK string) (crypto.PrivateKey, error) {
    var oidPrivateKeyRsaPss = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
    block, _ := pem.Decode([]byte(pemEncodedPK))
    if block == nil {
        return nil, errors.New("empty block")
    }

    // taken from crypto/x509/pkcs8.go
    type pkcs8 struct {
        Version    int
        Algo       pkix.AlgorithmIdentifier
        PrivateKey []byte
        // optional attributes omitted.
    }
    var privKey pkcs8
    if _, err := asn1.Unmarshal(block.Bytes, &privKey); err != nil {
        return nil, err
    }

    if privKey.Algo.Algorithm.Equal(oidPrivateKeyRsaPss) {
        rsaPrivKey, err := x509.ParsePKCS1PrivateKey(privKey.PrivateKey)
        if err == nil {
            return rsaPrivKey, nil
        }
    }

    return nil, errors.New("unknown algorithm")
}

In order to let the client reuse the underlying connection we just need to read the body entirely and close it before we issue a new HTTP request.

package main

import (
    "context"
    "io"
    "io/ioutil"
    "log"
    "net/http"
    "net/http/httptrace"
)

func main() {
    // client trace to log whether the request's underlying tcp connection was re-used
    clientTrace := &httptrace.ClientTrace{
        GotConn: func(info httptrace.GotConnInfo) { log.Printf("conn was reused: %t", info.Reused) },
    }
    traceCtx := httptrace.WithClientTrace(context.Background(), clientTrace)

    // 1st request
    req, err := http.NewRequestWithContext(traceCtx, http.MethodGet, "http://example.com", nil)
    if err != nil {
        log.Fatal(err)
    }
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
    if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
        log.Fatal(err)
    }
    res.Body.Close()
    // 2nd request
    req, err = http.NewRequestWithContext(traceCtx, http.MethodGet, "http://example.com", nil)
    if err != nil {
        log.Fatal(err)
    }
    _, err = http.DefaultClient.Do(req)
    if err != nil {
        log.Fatal(err)
    }
}

go http 参数设置示例

newClient := &http.Client{

        Timeout: time.Minute * 1, //设置超时时间

        Transport: &http.Transport{

            Dial: (&net.Dialer{

                Timeout:   30 * time.Second, //限制建立TCP连接的时间

                KeepAlive: 30 * time.Second,

            }).Dial,

            TLSHandshakeTimeout:   10 * time.Second, //限制 TLS握手的时间

            ResponseHeaderTimeout: 10 * time.Second, //限制读取response header的时间,默认 timeout + 5*time.Second

            ExpectContinueTimeout: 1 * time.Second,  //限制client在发送包含 Expect: 100-continue的header到收到继续发送body的response之间的时间等待。

            MaxIdleConns:          2,                //所有host的连接池最大连接数量,默认无穷大

            MaxIdleConnsPerHost:   1,                //每个host的连接池最大空闲连接数,默认2

            MaxConnsPerHost:       1,                //每个host的最大连接数量

            IdleConnTimeout:       3 * time.Minute,  //how long an idle connection is kept in the connection pool.
            TLSClientConfig:     &tls.Config{InsecureSkipVerify: true},

        },

    }