问:
OpenSSL BIO_read on string returns incomplete base64 encoding
I am trying to Base64 encode an RSA key after converting it to a decimal string in OpenSSL. I am able to encode most of the string, except for the last few characters and I really don't know why. I know there is a one-line function which can do this in EVP, but I already tried it outside of a test program, and I get really strange memory errors.

My code:

```<code>char *rsa_string = BN_bn2dec(n);

printf("RSA modulus as BigNumber: %s\n", rsa_string);

BIO *base64_bio = BIO_new(BIO_f_base64());
BIO *rsa_bio = BIO_new(BIO_s_mem());

BIO_set_flags(base64_bio, BIO_FLAGS_BASE64_NO_NL);
BIO_push(base64_bio, rsa_bio);
int bytes_wrote = BIO_write(base64_bio, rsa_string, strlen(rsa_string));

int size = (((bytes_wrote / 3) * 4) + 1);
char *base64_encoded_key = malloc(size);
memset(base64_encoded_key, 0, size);

BIO_read(rsa_bio, base64_encoded_key, size);

printf("PEM base64 encoded key: %s\n", base64_encoded_key);
</code>```

The value of rsa_string:

24313072237482078080153238679657972370698125455764727604271323979485556075246432578166301643940422426917948305745382409095484476466658578953561552837314705043006862929591710426227781122807468842903611989398403414596798482701682344649614368612160626447765390887911656651474459060185299697662496646333059927160952849254412616907773180781994902777839713317482262499105976583975621942282154132092996199104128448823598401942504647814124310345584957610465014752297210548757190951415912761894769725791618353941501561569896413562323669731189309270885282683237856701825718378848399084628386291389996469470694254685203803176643

The Base64 encoding:

MjQzMTMwNzIyMzc0ODIwNzgwODAxNTMyMzg2Nzk2NTc5NzIzNzA2OTgxMjU0NTU3NjQ3Mjc2MDQyNzEzMjM5Nzk0ODU1NTYwNzUyNDY0MzI1NzgxNjYzMDE2NDM5NDA0MjI0MjY5MTc5NDgzMDU3NDUzODI0MDkwOTU0ODQ0NzY0NjY2NTg1Nzg5NTM1NjE1NTI4MzczMTQ3MDUwNDMwMDY4NjI5Mjk1OTE3MTA0MjYyMjc3ODExMjI4MDc0Njg4NDI5MDM2MTE5ODkzOTg0MDM0MTQ1OTY3OTg0ODI3MDE2ODIzNDQ2NDk2MTQzNjg2MTIxNjA2MjY0NDc3NjUzOTA4ODc5MTE2NTY2NTE0NzQ0NTkwNjAxODUyOTk2OTc2NjI0OTY2NDYzMzMwNTk5MjcxNjA5NTI4NDkyNTQ0MTI2MTY5MDc3NzMxODA3ODE5OTQ5MDI3Nzc4Mzk3MTMzMTc0ODIyNjI0OTkxMDU5NzY1ODM5NzU2MjE5NDIyODIxNTQxMzIwOTI5OTYxOTkxMDQxMjg0NDg4MjM1OTg0MDE5NDI1MDQ2NDc4MTQxMjQzMTAzNDU1ODQ5NTc2MTA0NjUwMTQ3NTIyOTcyMTA1NDg3NTcxOTA5NTE0MTU5MTI3NjE4OTQ3Njk3MjU3OTE2MTgzNTM5NDE1MDE1NjE1Njk4OTY0MTM1NjIzMjM2Njk3MzExODkzMDkyNzA4ODUyODI2ODMyMzc4NTY3MDE4MjU3MTgzNzg4NDgzOTkwODQ2MjgzODYyOTEzODk5OTY0Njk0NzA2OTQyNTQ2ODUyMDM4MDMxNzY2

I compare this output to other programs which encode to Base64, and notice that my program is off by 4 characters (NDM=). Why is that?

What I have tried:

OpenSSL's BIO documentation - https://www.openssl.org/docs/manmaster/man3/BIO_f_base64.html

OpenSSL's source code - https://github.com/openssl/openssl/blob/d9f073575fdb07b486cd1b38974cd177687ccc1e/apps/rand.c

Different orderings of the BIOs in the BIO operations, and this is the only configuration that produces a Base64 output.

Providing the Base64 BIO read output buffer much more memory than is needed (just in case size was miscalculated).

I tried calling read() twice, but the second call returns -1, which apparently could mean the BIO thinks there is nothing left to read.

Based on what I saw from the examples, what I have seems right. Why isn't the Base64 filter producing the entire string?

Notes:

This is just a test program to figure out how to use the APIs, thus I don't flush the BIO.

Before I added the BIO_set_flags(base64_bio, BIO_FLAGS_BASE64_NO_NL) code, the encoding was off by 40 characters... I also do not understand this.

Any help or direction is appreciated. Thanks!

答:
The source of the data to be base64-encoded notwithstanding, a very basic operation that exhibits how it is done is as follows.

Generate a random block of 256 bytes of data.

Open a Base64 BIO and configure it.

Open a basic memory bio

Chain the aforementioned two bios.

Write data through the bio chain.

Flush the bio chain.

Reap the data from the memory bio.

Close the full BIO chain.

That's pretty much it. Now the code:

```<code>#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>

#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/randerr.h>

int main()
{
    // generate a random 256 byte block
    uint8_t hdata[256] = {0};
    RAND_bytes(hdata, sizeof hdata);
    hdata[0] &=0x7F; // don't ask.

    // display in stdout just to prove it's there
    BIO_dump_fp(stdout, hdata, sizeof hdata);

    // configure base64 filter
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    // configure a memory bio
    BIO *bmem = BIO_new(BIO_s_mem());

    // chain bios
    BIO *bio = BIO_push(b64, bmem);

    // write to target chain and flush
    BIO_write(bio, hdata, sizeof hdata);
    BIO_flush(bio);

    // reap memory buffer
    char *ptr = NULL;
    long len = BIO_get_mem_data(bmem, &ptr);

    // dump the converted data to stdout
    fwrite(ptr, (size_t)len, 1, stdout);
    fputc('\n', stdout);
    fflush(stdout);

    // close BIO chain
    BIO_free_all(bio);

    return EXIT_SUCCESS;
}
</code>```

Sample Output (varies, obviously)

```<code>0000 - 5b 94 cd 8b 1c 45 b9 5a-8c 5d f1 e3 08 31 55 8f   [....E.Z.]...1U.
0010 - 8b 3c 29 7f 5d b1 72 82-12 6d 24 3f 04 6e 83 72   .<).].r..m$?.n.r
0020 - 1c 1d 01 5c 54 3b 2e c8-cc 47 5a 2f db ec 47 06   ...\T;...GZ/..G.
0030 - 95 25 13 f4 3b 92 2c c0-b6 88 41 d1 62 f7 f2 e4   .%..;.,...A.b...
0040 - 45 22 14 3a fc 1d a3 3b-b3 79 5b f0 c1 06 cb 56   E".:...;.y[....V
0050 - 87 f8 61 1e 82 9f 1b f0-fa 43 90 a0 12 18 28 40   ..a......C....(@
0060 - 88 32 ff f9 62 9f d6 eb-9c dc 69 fa 3a ca a5 ea   .2..b.....i.:...
0070 - 20 bb 62 9d 86 e4 76 8f-20 4f 19 42 a7 0d 15 c7    .b...v. O.B....
0080 - 83 78 79 20 b2 a3 44 64-bf 7f a0 84 11 a4 38 96   .xy ..Dd......8.
0090 - 17 83 18 96 84 6b df 94-e3 66 e2 88 63 58 d8 8f   .....k...f..cX..
00a0 - 49 67 b8 78 68 e2 8c 8b-55 cf 27 84 4c 35 91 80   Ig.xh...U.'.L5..
00b0 - 0c a0 63 2c f7 c0 c6 db-30 aa d9 8b 64 cb d2 8d   ..c,....0...d...
00c0 - c8 71 f9 0e 93 25 66 b4-c7 65 fc 85 a9 93 93 b7   .q...%f..e......
00d0 - 72 30 e9 72 e0 26 16 2c-a3 02 54 bd f6 d2 4a 8f   r0.r.&.,..T...J.
00e0 - 0b 9b 7a 6c 35 cd 2c 80-f8 50 0e 31 a9 0b 39 0c   ..zl5.,..P.1..9.
00f0 - b1 cf 67 b8 65 75 a3 98-ee 0b d5 6f a0 61 8b df   ..g.eu.....o.a..
W5TNixxFuVqMXfHjCDFVj4s8KX9dsXKCEm0kPwRug3IcHQFcVDsuyMxHWi/b7EcGlSUT9DuSLMC2iEHRYvfy5EUiFDr8HaM7s3lb8MEGy1aH+GEegp8b8PpDkKASGChAiDL/+WKf1uuc3Gn6Osql6iC7Yp2G5HaPIE8ZQqcNFceDeHkgsqNEZL9/oIQRpDiWF4MYloRr35TjZuKIY1jYj0lnuHho4oyLVc8nhEw1kYAMoGMs98DG2zCq2Ytky9KNyHH5DpMlZrTHZfyFqZOTt3Iw6XLgJhYsowJUvfbSSo8Lm3psNc0sgPhQDjGpCzkMsc9nuGV1o5juC9VvoGGL3w==
</code>```

The flush is important. When you consider how a base64 stream filter could work, it will wait for 3 octets before emitting four. It could be even more elaborate internally, but mere mortals would likely write it as such. Therefore, it doesn't know when you are "done" writing data, ending in a state that could be on a partial/incomplete triplet until you say so, and you do that via a flush of the bio chain.

Your Text String, Base64 Encoded

Doing the same for your text string is extremely similar to the prior code. Obviously the source data is different, but the rest will be similar.

```<code>#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/bio.h>
#include <openssl/evp.h>

int main()
{
    const char *str =
    "2431307223748207808015323867965797237069812545576472760427132397948555"
    "6075246432578166301643940422426917948305745382409095484476466658578953"
    "5615528373147050430068629295917104262277811228074688429036119893984034"
    "1459679848270168234464961436861216062644776539088791165665147445906018"
    "5299697662496646333059927160952849254412616907773180781994902777839713"
    "3174822624991059765839756219422821541320929961991041284488235984019425"
    "0464781412431034558495761046501475229721054875719095141591276189476972"
    "5791618353941501561569896413562323669731189309270885282683237856701825"
    "718378848399084628386291389996469470694254685203803176643";

    const size_t slen = strlen(str);

    // display in stdout
    BIO_dump_fp(stdout, str, (int)slen);

    // configure base64 filter
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    // configure a memory bio
    BIO *bmem = BIO_new(BIO_s_mem());

    // chain bios
    BIO *bio = BIO_push(b64, bmem);

    // write to target chain and flush
    BIO_write(bio, str, (int)slen);
    BIO_flush(bio);

    // reap memory buffer
    char *ptr = NULL;
    long len = BIO_get_mem_data(bmem, &ptr);

    // dump the converted data to stdout
    fwrite(ptr, (size_t)len, 1, stdout);
    fputc('\n', stdout);
    fflush(stdout);

    // close BIO chain
    BIO_free_all(bio);

    return EXIT_SUCCESS;
}
</code>```

Output

```<code>0000 - 32 34 33 31 33 30 37 32-32 33 37 34 38 32 30 37   2431307223748207
0010 - 38 30 38 30 31 35 33 32-33 38 36 37 39 36 35 37   8080153238679657
0020 - 39 37 32 33 37 30 36 39-38 31 32 35 34 35 35 37   9723706981254557
0030 - 36 34 37 32 37 36 30 34-32 37 31 33 32 33 39 37   6472760427132397
0040 - 39 34 38 35 35 35 36 30-37 35 32 34 36 34 33 32   9485556075246432
0050 - 35 37 38 31 36 36 33 30-31 36 34 33 39 34 30 34   5781663016439404
0060 - 32 32 34 32 36 39 31 37-39 34 38 33 30 35 37 34   2242691794830574
0070 - 35 33 38 32 34 30 39 30-39 35 34 38 34 34 37 36   5382409095484476
0080 - 34 36 36 36 35 38 35 37-38 39 35 33 35 36 31 35   4666585789535615
0090 - 35 32 38 33 37 33 31 34-37 30 35 30 34 33 30 30   5283731470504300
00a0 - 36 38 36 32 39 32 39 35-39 31 37 31 30 34 32 36   6862929591710426
00b0 - 32 32 37 37 38 31 31 32-32 38 30 37 34 36 38 38   2277811228074688
00c0 - 34 32 39 30 33 36 31 31-39 38 39 33 39 38 34 30   4290361198939840
00d0 - 33 34 31 34 35 39 36 37-39 38 34 38 32 37 30 31   3414596798482701
00e0 - 36 38 32 33 34 34 36 34-39 36 31 34 33 36 38 36   6823446496143686
00f0 - 31 32 31 36 30 36 32 36-34 34 37 37 36 35 33 39   1216062644776539
0100 - 30 38 38 37 39 31 31 36-35 36 36 35 31 34 37 34   0887911656651474
0110 - 34 35 39 30 36 30 31 38-35 32 39 39 36 39 37 36   4590601852996976
0120 - 36 32 34 39 36 36 34 36-33 33 33 30 35 39 39 32   6249664633305992
0130 - 37 31 36 30 39 35 32 38-34 39 32 35 34 34 31 32   7160952849254412
0140 - 36 31 36 39 30 37 37 37-33 31 38 30 37 38 31 39   6169077731807819
0150 - 39 34 39 30 32 37 37 37-38 33 39 37 31 33 33 31   9490277783971331
0160 - 37 34 38 32 32 36 32 34-39 39 31 30 35 39 37 36   7482262499105976
0170 - 35 38 33 39 37 35 36 32-31 39 34 32 32 38 32 31   5839756219422821
0180 - 35 34 31 33 32 30 39 32-39 39 36 31 39 39 31 30   5413209299619910
0190 - 34 31 32 38 34 34 38 38-32 33 35 39 38 34 30 31   4128448823598401
01a0 - 39 34 32 35 30 34 36 34-37 38 31 34 31 32 34 33   9425046478141243
01b0 - 31 30 33 34 35 35 38 34-39 35 37 36 31 30 34 36   1034558495761046
01c0 - 35 30 31 34 37 35 32 32-39 37 32 31 30 35 34 38   5014752297210548
01d0 - 37 35 37 31 39 30 39 35-31 34 31 35 39 31 32 37   7571909514159127
01e0 - 36 31 38 39 34 37 36 39-37 32 35 37 39 31 36 31   6189476972579161
01f0 - 38 33 35 33 39 34 31 35-30 31 35 36 31 35 36 39   8353941501561569
0200 - 38 39 36 34 31 33 35 36-32 33 32 33 36 36 39 37   8964135623236697
0210 - 33 31 31 38 39 33 30 39-32 37 30 38 38 35 32 38   3118930927088528
0220 - 32 36 38 33 32 33 37 38-35 36 37 30 31 38 32 35   2683237856701825
0230 - 37 31 38 33 37 38 38 34-38 33 39 39 30 38 34 36   7183788483990846
0240 - 32 38 33 38 36 32 39 31-33 38 39 39 39 36 34 36   2838629138999646
0250 - 39 34 37 30 36 39 34 32-35 34 36 38 35 32 30 33   9470694254685203
0260 - 38 30 33 31 37 36 36 34-33                        803176643
MjQzMTMwNzIyMzc0ODIwNzgwODAxNTMyMzg2Nzk2NTc5NzIzNzA2OTgxMjU0NTU3NjQ3Mjc2MDQyNzEzMjM5Nzk0ODU1NTYwNzUyNDY0MzI1NzgxNjYzMDE2NDM5NDA0MjI0MjY5MTc5NDgzMDU3NDUzODI0MDkwOTU0ODQ0NzY0NjY2NTg1Nzg5NTM1NjE1NTI4MzczMTQ3MDUwNDMwMDY4NjI5Mjk1OTE3MTA0MjYyMjc3ODExMjI4MDc0Njg4NDI5MDM2MTE5ODkzOTg0MDM0MTQ1OTY3OTg0ODI3MDE2ODIzNDQ2NDk2MTQzNjg2MTIxNjA2MjY0NDc3NjUzOTA4ODc5MTE2NTY2NTE0NzQ0NTkwNjAxODUyOTk2OTc2NjI0OTY2NDYzMzMwNTk5MjcxNjA5NTI4NDkyNTQ0MTI2MTY5MDc3NzMxODA3ODE5OTQ5MDI3Nzc4Mzk3MTMzMTc0ODIyNjI0OTkxMDU5NzY1ODM5NzU2MjE5NDIyODIxNTQxMzIwOTI5OTYxOTkxMDQxMjg0NDg4MjM1OTg0MDE5NDI1MDQ2NDc4MTQxMjQzMTAzNDU1ODQ5NTc2MTA0NjUwMTQ3NTIyOTcyMTA1NDg3NTcxOTA5NTE0MTU5MTI3NjE4OTQ3Njk3MjU3OTE2MTgzNTM5NDE1MDE1NjE1Njk4OTY0MTM1NjIzMjM2Njk3MzExODkzMDkyNzA4ODUyODI2ODMyMzc4NTY3MDE4MjU3MTgzNzg4NDgzOTkwODQ2MjgzODYyOTEzODk5OTY0Njk0NzA2OTQyNTQ2ODUyMDM4MDMxNzY2NDM=
</code>```

A copy of that base64 line decoded at base64decode.org will line up perfectly with your source string.

BIGNUM Base64 Encoding

On the off-chance my suspicion is correct, and what your ultimate goal is a base64 encoding of the bignum itself, that too is doable, with barely any more work. Using the original source string, we can create a BIGNUM, then send that through the base64 filtered bio chain just as before:

```<code>#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>

#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/evp.h>

int main()
{
    const char *str =
    "2431307223748207808015323867965797237069812545576472760427132397948555"
    "6075246432578166301643940422426917948305745382409095484476466658578953"
    "5615528373147050430068629295917104262277811228074688429036119893984034"
    "1459679848270168234464961436861216062644776539088791165665147445906018"
    "5299697662496646333059927160952849254412616907773180781994902777839713"
    "3174822624991059765839756219422821541320929961991041284488235984019425"
    "0464781412431034558495761046501475229721054875719095141591276189476972"
    "5791618353941501561569896413562323669731189309270885282683237856701825"
    "718378848399084628386291389996469470694254685203803176643";

    // convert relaly big integer asci string to a bignum
    BIGNUM *bn = NULL;
    if (BN_asc2bn(&bn, str) == 1)
    {
        // convert the big number to big-endian binary.
        int nbytes = BN_num_bytes(bn);
        unsigned char *bin = OPENSSL_malloc(nbytes);
        BN_bn2bin(bn, bin);

        // dump to stdout
        BIO_dump_fp(stdout, bin, nbytes);

        // configure base64 filter
        BIO *b64 = BIO_new(BIO_f_base64());
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

        // configure bio chain
        BIO *bmem = BIO_new(BIO_s_mem());
        BIO *bio = BIO_push(b64, bmem);
        BIO_write(bio, bin, nbytes);;
        BIO_flush(bio);

        // no longer need the BN or buffer
        OPENSSL_clear_free(bin, nbytes);
        BN_free(bn);

        // reap memory buffer
        char *ptr = NULL;
        long len = BIO_get_mem_data(bmem, &ptr);

        // dump the converted data to stdout
        fwrite(ptr, (size_t)len, 1, stdout);
        fputc('\n', stdout);
        fflush(stdout);

        // close BIO chain
        BIO_free_all(bio);
    }

    return EXIT_SUCCESS;
}
</code>```

Output

```<code>0000 - c0 98 bc ce e0 43 b1 06-de 88 ff c2 f2 02 6d 08   .....C........m.
0010 - 92 99 30 4d 06 c4 e1 39-18 48 f8 24 bd a6 7e e0   ..0M...9.H.$..~.
0020 - 3d c3 7a 59 1d ff 70 a6-2e 8b 5d c9 c6 3d 38 cb   =.zY..p...]..=8.
0030 - aa f7 4a d6 1b 24 54 c4-9f 4f 74 b4 52 2b 9a 89   ..J..$T..Ot.R+..
0040 - 3b 72 d8 ce 60 fa dc 72-36 9d 0a 31 45 32 54 94   ;r..`..r6..1E2T.
0050 - 61 c4 9e 05 32 68 08 d8-d8 41 e3 0c d5 b3 81 13   a...2h...A......
0060 - ec 5c 95 c5 23 a7 71 a3-0d c0 e6 13 04 14 db 6c   .\..#.q........l
0070 - 9d f2 10 e0 52 ff 44 be-a9 c4 8a 8e ee 13 3f 4e   ....R.D.......?N
0080 - a1 3e 04 72 ea 35 5f 42-04 e7 aa b0 82 df c1 07   .>.r.5_B........
0090 - a6 db 7d d5 81 b7 33 cf-a9 bc 95 76 63 ae 9b 7a   ..}...3....vc..z
00a0 - f9 11 79 c0 31 8d e0 53-11 e6 34 3d a9 a6 53 9c   ..y.1..S..4=..S.
00b0 - 90 a6 68 da 0a 94 05 b3-0e 79 be a6 8b 82 4c 27   ..h......y....L'
00c0 - 76 3e 76 59 81 db dd dd-27 c4 ea cd b1 d9 b1 86   v>vY....'.......
00d0 - e3 7b f0 9a 7c d5 3c aa-ae a1 8d f0 96 73 2c 96   .{..|.<......s,.
00e0 - 53 01 4e 49 2e 4b ed 86-cd 98 60 99 8b 5a 21 c5   S.NI.K....`..Z!.
00f0 - 1a e6 b7 1d 45 8f d1 bf-83 f9 bc e6 46 14 7e c3   ....E.......F.~.
wJi8zuBDsQbeiP/C8gJtCJKZME0GxOE5GEj4JL2mfuA9w3pZHf9wpi6LXcnGPTjLqvdK1hskVMSfT3S0UiuaiTty2M5g+txyNp0KMUUyVJRhxJ4FMmgI2NhB4wzVs4ET7FyVxSOncaMNwOYTBBTbbJ3yEOBS/0S+qcSKju4TP06hPgRy6jVfQgTnqrCC38EHptt91YG3M8+pvJV2Y66bevkRecAxjeBTEeY0PammU5yQpmjaCpQFsw55vqaLgkwndj52WYHb3d0nxOrNsdmxhuN78Jp81TyqrqGN8JZzLJZTAU5JLkvths2YYJmLWiHFGua3HUWP0b+D+bzmRhR+ww==
</code>```

The above shows the 256 bytes in the console dump as representing the number in big-endian binary form. That is the data that is base64 encoded and produces final line of output. The code should look very familiar, as it is basically identical to the first sample in this answer; only the source of data is different.

I suspect this is what you will need eventually, though you're posted code suggests you're already starting with a bignum, so the beginning of the above code that creates a bignum from the string is already done.

Body:
I am trying to Base64 encode an RSA key after converting it to a decimal string in OpenSSL. I am able to encode most of the string, except for the last few characters and I really don't know why. I know there is a one-line function which can do this in EVP, but I already tried it outside of a test program, and I get really strange memory errors.

My code:

char *rsa_string = BN_bn2dec(n);

printf("RSA modulus as BigNumber: %s\n", rsa_string);

BIO *base64_bio = BIO_new(BIO_f_base64());
BIO *rsa_bio = BIO_new(BIO_s_mem());

BIO_set_flags(base64_bio, BIO_FLAGS_BASE64_NO_NL);
BIO_push(base64_bio, rsa_bio);
int bytes_wrote = BIO_write(base64_bio, rsa_string, strlen(rsa_string));

int size = (((bytes_wrote / 3) * 4) + 1);
char *base64_encoded_key = malloc(size);
memset(base64_encoded_key, 0, size);

BIO_read(rsa_bio, base64_encoded_key, size);

printf("PEM base64 encoded key: %s\n", base64_encoded_key);

The value of rsa_string:

24313072237482078080153238679657972370698125455764727604271323979485556075246432578166301643940422426917948305745382409095484476466658578953561552837314705043006862929591710426227781122807468842903611989398403414596798482701682344649614368612160626447765390887911656651474459060185299697662496646333059927160952849254412616907773180781994902777839713317482262499105976583975621942282154132092996199104128448823598401942504647814124310345584957610465014752297210548757190951415912761894769725791618353941501561569896413562323669731189309270885282683237856701825718378848399084628386291389996469470694254685203803176643

The Base64 encoding:

MjQzMTMwNzIyMzc0ODIwNzgwODAxNTMyMzg2Nzk2NTc5NzIzNzA2OTgxMjU0NTU3NjQ3Mjc2MDQyNzEzMjM5Nzk0ODU1NTYwNzUyNDY0MzI1NzgxNjYzMDE2NDM5NDA0MjI0MjY5MTc5NDgzMDU3NDUzODI0MDkwOTU0ODQ0NzY0NjY2NTg1Nzg5NTM1NjE1NTI4MzczMTQ3MDUwNDMwMDY4NjI5Mjk1OTE3MTA0MjYyMjc3ODExMjI4MDc0Njg4NDI5MDM2MTE5ODkzOTg0MDM0MTQ1OTY3OTg0ODI3MDE2ODIzNDQ2NDk2MTQzNjg2MTIxNjA2MjY0NDc3NjUzOTA4ODc5MTE2NTY2NTE0NzQ0NTkwNjAxODUyOTk2OTc2NjI0OTY2NDYzMzMwNTk5MjcxNjA5NTI4NDkyNTQ0MTI2MTY5MDc3NzMxODA3ODE5OTQ5MDI3Nzc4Mzk3MTMzMTc0ODIyNjI0OTkxMDU5NzY1ODM5NzU2MjE5NDIyODIxNTQxMzIwOTI5OTYxOTkxMDQxMjg0NDg4MjM1OTg0MDE5NDI1MDQ2NDc4MTQxMjQzMTAzNDU1ODQ5NTc2MTA0NjUwMTQ3NTIyOTcyMTA1NDg3NTcxOTA5NTE0MTU5MTI3NjE4OTQ3Njk3MjU3OTE2MTgzNTM5NDE1MDE1NjE1Njk4OTY0MTM1NjIzMjM2Njk3MzExODkzMDkyNzA4ODUyODI2ODMyMzc4NTY3MDE4MjU3MTgzNzg4NDgzOTkwODQ2MjgzODYyOTEzODk5OTY0Njk0NzA2OTQyNTQ2ODUyMDM4MDMxNzY2

I compare this output to other programs which encode to Base64, and notice that my program is off by 4 characters (NDM=). Why is that?

What I have tried:

OpenSSL's BIO documentation - https://www.openssl.org/docs/manmaster/man3/BIO_f_base64.html

OpenSSL's source code - https://github.com/openssl/openssl/blob/d9f073575fdb07b486cd1b38974cd177687ccc1e/apps/rand.c

Different orderings of the BIOs in the BIO operations, and this is the only configuration that produces a Base64 output.

Providing the Base64 BIO read output buffer much more memory than is needed (just in case size was miscalculated).

I tried calling read() twice, but the second call returns -1, which apparently could mean the BIO thinks there is nothing left to read.

Based on what I saw from the examples, what I have seems right. Why isn't the Base64 filter producing the entire string?

Notes:

This is just a test program to figure out how to use the APIs, thus I don't flush the BIO.

Before I added the BIO_set_flags(base64_bio, BIO_FLAGS_BASE64_NO_NL) code, the encoding was off by 40 characters... I also do not understand this.

Any help or direction is appreciated. Thanks!

Body:
The source of the data to be base64-encoded notwithstanding, a very basic operation that exhibits how it is done is as follows.

Generate a random block of 256 bytes of data.

Open a Base64 BIO and configure it.

Open a basic memory bio

Chain the aforementioned two bios.

Write data through the bio chain.

Flush the bio chain.

Reap the data from the memory bio.

Close the full BIO chain.

That's pretty much it. Now the code:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>

#include <openssl/bio.h>
#include <openssl/rand.h>
#include <openssl/randerr.h>

int main()
{
    // generate a random 256 byte block
    uint8_t hdata[256] = {0};
    RAND_bytes(hdata, sizeof hdata);
    hdata[0] &=0x7F; // don't ask.

    // display in stdout just to prove it's there
    BIO_dump_fp(stdout, hdata, sizeof hdata);

    // configure base64 filter
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    // configure a memory bio
    BIO *bmem = BIO_new(BIO_s_mem());

    // chain bios
    BIO *bio = BIO_push(b64, bmem);

    // write to target chain and flush
    BIO_write(bio, hdata, sizeof hdata);
    BIO_flush(bio);

    // reap memory buffer
    char *ptr = NULL;
    long len = BIO_get_mem_data(bmem, &ptr);

    // dump the converted data to stdout
    fwrite(ptr, (size_t)len, 1, stdout);
    fputc('\n', stdout);
    fflush(stdout);

    // close BIO chain
    BIO_free_all(bio);

    return EXIT_SUCCESS;
}

Sample Output (varies, obviously)

0000 - 5b 94 cd 8b 1c 45 b9 5a-8c 5d f1 e3 08 31 55 8f   [....E.Z.]...1U.
0010 - 8b 3c 29 7f 5d b1 72 82-12 6d 24 3f 04 6e 83 72   .<).].r..m$?.n.r
0020 - 1c 1d 01 5c 54 3b 2e c8-cc 47 5a 2f db ec 47 06   ...\T;...GZ/..G.
0030 - 95 25 13 f4 3b 92 2c c0-b6 88 41 d1 62 f7 f2 e4   .%..;.,...A.b...
0040 - 45 22 14 3a fc 1d a3 3b-b3 79 5b f0 c1 06 cb 56   E".:...;.y[....V
0050 - 87 f8 61 1e 82 9f 1b f0-fa 43 90 a0 12 18 28 40   ..a......C....(@
0060 - 88 32 ff f9 62 9f d6 eb-9c dc 69 fa 3a ca a5 ea   .2..b.....i.:...
0070 - 20 bb 62 9d 86 e4 76 8f-20 4f 19 42 a7 0d 15 c7    .b...v. O.B....
0080 - 83 78 79 20 b2 a3 44 64-bf 7f a0 84 11 a4 38 96   .xy ..Dd......8.
0090 - 17 83 18 96 84 6b df 94-e3 66 e2 88 63 58 d8 8f   .....k...f..cX..
00a0 - 49 67 b8 78 68 e2 8c 8b-55 cf 27 84 4c 35 91 80   Ig.xh...U.'.L5..
00b0 - 0c a0 63 2c f7 c0 c6 db-30 aa d9 8b 64 cb d2 8d   ..c,....0...d...
00c0 - c8 71 f9 0e 93 25 66 b4-c7 65 fc 85 a9 93 93 b7   .q...%f..e......
00d0 - 72 30 e9 72 e0 26 16 2c-a3 02 54 bd f6 d2 4a 8f   r0.r.&.,..T...J.
00e0 - 0b 9b 7a 6c 35 cd 2c 80-f8 50 0e 31 a9 0b 39 0c   ..zl5.,..P.1..9.
00f0 - b1 cf 67 b8 65 75 a3 98-ee 0b d5 6f a0 61 8b df   ..g.eu.....o.a..
W5TNixxFuVqMXfHjCDFVj4s8KX9dsXKCEm0kPwRug3IcHQFcVDsuyMxHWi/b7EcGlSUT9DuSLMC2iEHRYvfy5EUiFDr8HaM7s3lb8MEGy1aH+GEegp8b8PpDkKASGChAiDL/+WKf1uuc3Gn6Osql6iC7Yp2G5HaPIE8ZQqcNFceDeHkgsqNEZL9/oIQRpDiWF4MYloRr35TjZuKIY1jYj0lnuHho4oyLVc8nhEw1kYAMoGMs98DG2zCq2Ytky9KNyHH5DpMlZrTHZfyFqZOTt3Iw6XLgJhYsowJUvfbSSo8Lm3psNc0sgPhQDjGpCzkMsc9nuGV1o5juC9VvoGGL3w==

The flush is important. When you consider how a base64 stream filter could work, it will wait for 3 octets before emitting four. It could be even more elaborate internally, but mere mortals would likely write it as such. Therefore, it doesn't know when you are "done" writing data, ending in a state that could be on a partial/incomplete triplet until you say so, and you do that via a flush of the bio chain.

Your Text String, Base64 Encoded

Doing the same for your text string is extremely similar to the prior code. Obviously the source data is different, but the rest will be similar.

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/bio.h>
#include <openssl/evp.h>

int main()
{
    const char *str =
    "2431307223748207808015323867965797237069812545576472760427132397948555"
    "6075246432578166301643940422426917948305745382409095484476466658578953"
    "5615528373147050430068629295917104262277811228074688429036119893984034"
    "1459679848270168234464961436861216062644776539088791165665147445906018"
    "5299697662496646333059927160952849254412616907773180781994902777839713"
    "3174822624991059765839756219422821541320929961991041284488235984019425"
    "0464781412431034558495761046501475229721054875719095141591276189476972"
    "5791618353941501561569896413562323669731189309270885282683237856701825"
    "718378848399084628386291389996469470694254685203803176643";

    const size_t slen = strlen(str);

    // display in stdout
    BIO_dump_fp(stdout, str, (int)slen);

    // configure base64 filter
    BIO *b64 = BIO_new(BIO_f_base64());
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

    // configure a memory bio
    BIO *bmem = BIO_new(BIO_s_mem());

    // chain bios
    BIO *bio = BIO_push(b64, bmem);

    // write to target chain and flush
    BIO_write(bio, str, (int)slen);
    BIO_flush(bio);

    // reap memory buffer
    char *ptr = NULL;
    long len = BIO_get_mem_data(bmem, &ptr);

    // dump the converted data to stdout
    fwrite(ptr, (size_t)len, 1, stdout);
    fputc('\n', stdout);
    fflush(stdout);

    // close BIO chain
    BIO_free_all(bio);

    return EXIT_SUCCESS;
}

Output

0000 - 32 34 33 31 33 30 37 32-32 33 37 34 38 32 30 37   2431307223748207
0010 - 38 30 38 30 31 35 33 32-33 38 36 37 39 36 35 37   8080153238679657
0020 - 39 37 32 33 37 30 36 39-38 31 32 35 34 35 35 37   9723706981254557
0030 - 36 34 37 32 37 36 30 34-32 37 31 33 32 33 39 37   6472760427132397
0040 - 39 34 38 35 35 35 36 30-37 35 32 34 36 34 33 32   9485556075246432
0050 - 35 37 38 31 36 36 33 30-31 36 34 33 39 34 30 34   5781663016439404
0060 - 32 32 34 32 36 39 31 37-39 34 38 33 30 35 37 34   2242691794830574
0070 - 35 33 38 32 34 30 39 30-39 35 34 38 34 34 37 36   5382409095484476
0080 - 34 36 36 36 35 38 35 37-38 39 35 33 35 36 31 35   4666585789535615
0090 - 35 32 38 33 37 33 31 34-37 30 35 30 34 33 30 30   5283731470504300
00a0 - 36 38 36 32 39 32 39 35-39 31 37 31 30 34 32 36   6862929591710426
00b0 - 32 32 37 37 38 31 31 32-32 38 30 37 34 36 38 38   2277811228074688
00c0 - 34 32 39 30 33 36 31 31-39 38 39 33 39 38 34 30   4290361198939840
00d0 - 33 34 31 34 35 39 36 37-39 38 34 38 32 37 30 31   3414596798482701
00e0 - 36 38 32 33 34 34 36 34-39 36 31 34 33 36 38 36   6823446496143686
00f0 - 31 32 31 36 30 36 32 36-34 34 37 37 36 35 33 39   1216062644776539
0100 - 30 38 38 37 39 31 31 36-35 36 36 35 31 34 37 34   0887911656651474
0110 - 34 35 39 30 36 30 31 38-35 32 39 39 36 39 37 36   4590601852996976
0120 - 36 32 34 39 36 36 34 36-33 33 33 30 35 39 39 32   6249664633305992
0130 - 37 31 36 30 39 35 32 38-34 39 32 35 34 34 31 32   7160952849254412
0140 - 36 31 36 39 30 37 37 37-33 31 38 30 37 38 31 39   6169077731807819
0150 - 39 34 39 30 32 37 37 37-38 33 39 37 31 33 33 31   9490277783971331
0160 - 37 34 38 32 32 36 32 34-39 39 31 30 35 39 37 36   7482262499105976
0170 - 35 38 33 39 37 35 36 32-31 39 34 32 32 38 32 31   5839756219422821
0180 - 35 34 31 33 32 30 39 32-39 39 36 31 39 39 31 30   5413209299619910
0190 - 34 31 32 38 34 34 38 38-32 33 35 39 38 34 30 31   4128448823598401
01a0 - 39 34 32 35 30 34 36 34-37 38 31 34 31 32 34 33   9425046478141243
01b0 - 31 30 33 34 35 35 38 34-39 35 37 36 31 30 34 36   1034558495761046
01c0 - 35 30 31 34 37 35 32 32-39 37 32 31 30 35 34 38   5014752297210548
01d0 - 37 35 37 31 39 30 39 35-31 34 31 35 39 31 32 37   7571909514159127
01e0 - 36 31 38 39 34 37 36 39-37 32 35 37 39 31 36 31   6189476972579161
01f0 - 38 33 35 33 39 34 31 35-30 31 35 36 31 35 36 39   8353941501561569
0200 - 38 39 36 34 31 33 35 36-32 33 32 33 36 36 39 37   8964135623236697
0210 - 33 31 31 38 39 33 30 39-32 37 30 38 38 35 32 38   3118930927088528
0220 - 32 36 38 33 32 33 37 38-35 36 37 30 31 38 32 35   2683237856701825
0230 - 37 31 38 33 37 38 38 34-38 33 39 39 30 38 34 36   7183788483990846
0240 - 32 38 33 38 36 32 39 31-33 38 39 39 39 36 34 36   2838629138999646
0250 - 39 34 37 30 36 39 34 32-35 34 36 38 35 32 30 33   9470694254685203
0260 - 38 30 33 31 37 36 36 34-33                        803176643
MjQzMTMwNzIyMzc0ODIwNzgwODAxNTMyMzg2Nzk2NTc5NzIzNzA2OTgxMjU0NTU3NjQ3Mjc2MDQyNzEzMjM5Nzk0ODU1NTYwNzUyNDY0MzI1NzgxNjYzMDE2NDM5NDA0MjI0MjY5MTc5NDgzMDU3NDUzODI0MDkwOTU0ODQ0NzY0NjY2NTg1Nzg5NTM1NjE1NTI4MzczMTQ3MDUwNDMwMDY4NjI5Mjk1OTE3MTA0MjYyMjc3ODExMjI4MDc0Njg4NDI5MDM2MTE5ODkzOTg0MDM0MTQ1OTY3OTg0ODI3MDE2ODIzNDQ2NDk2MTQzNjg2MTIxNjA2MjY0NDc3NjUzOTA4ODc5MTE2NTY2NTE0NzQ0NTkwNjAxODUyOTk2OTc2NjI0OTY2NDYzMzMwNTk5MjcxNjA5NTI4NDkyNTQ0MTI2MTY5MDc3NzMxODA3ODE5OTQ5MDI3Nzc4Mzk3MTMzMTc0ODIyNjI0OTkxMDU5NzY1ODM5NzU2MjE5NDIyODIxNTQxMzIwOTI5OTYxOTkxMDQxMjg0NDg4MjM1OTg0MDE5NDI1MDQ2NDc4MTQxMjQzMTAzNDU1ODQ5NTc2MTA0NjUwMTQ3NTIyOTcyMTA1NDg3NTcxOTA5NTE0MTU5MTI3NjE4OTQ3Njk3MjU3OTE2MTgzNTM5NDE1MDE1NjE1Njk4OTY0MTM1NjIzMjM2Njk3MzExODkzMDkyNzA4ODUyODI2ODMyMzc4NTY3MDE4MjU3MTgzNzg4NDgzOTkwODQ2MjgzODYyOTEzODk5OTY0Njk0NzA2OTQyNTQ2ODUyMDM4MDMxNzY2NDM=

A copy of that base64 line decoded at base64decode.org will line up perfectly with your source string.

BIGNUM Base64 Encoding

On the off-chance my suspicion is correct, and what your ultimate goal is a base64 encoding of the bignum itself, that too is doable, with barely any more work. Using the original source string, we can create a BIGNUM, then send that through the base64 filtered bio chain just as before:

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>

#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/evp.h>

int main()
{
    const char *str =
    "2431307223748207808015323867965797237069812545576472760427132397948555"
    "6075246432578166301643940422426917948305745382409095484476466658578953"
    "5615528373147050430068629295917104262277811228074688429036119893984034"
    "1459679848270168234464961436861216062644776539088791165665147445906018"
    "5299697662496646333059927160952849254412616907773180781994902777839713"
    "3174822624991059765839756219422821541320929961991041284488235984019425"
    "0464781412431034558495761046501475229721054875719095141591276189476972"
    "5791618353941501561569896413562323669731189309270885282683237856701825"
    "718378848399084628386291389996469470694254685203803176643";

    // convert relaly big integer asci string to a bignum
    BIGNUM *bn = NULL;
    if (BN_asc2bn(&bn, str) == 1)
    {
        // convert the big number to big-endian binary.
        int nbytes = BN_num_bytes(bn);
        unsigned char *bin = OPENSSL_malloc(nbytes);
        BN_bn2bin(bn, bin);

        // dump to stdout
        BIO_dump_fp(stdout, bin, nbytes);

        // configure base64 filter
        BIO *b64 = BIO_new(BIO_f_base64());
        BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);

        // configure bio chain
        BIO *bmem = BIO_new(BIO_s_mem());
        BIO *bio = BIO_push(b64, bmem);
        BIO_write(bio, bin, nbytes);;
        BIO_flush(bio);

        // no longer need the BN or buffer
        OPENSSL_clear_free(bin, nbytes);
        BN_free(bn);

        // reap memory buffer
        char *ptr = NULL;
        long len = BIO_get_mem_data(bmem, &ptr);

        // dump the converted data to stdout
        fwrite(ptr, (size_t)len, 1, stdout);
        fputc('\n', stdout);
        fflush(stdout);

        // close BIO chain
        BIO_free_all(bio);
    }

    return EXIT_SUCCESS;
}

Output

0000 - c0 98 bc ce e0 43 b1 06-de 88 ff c2 f2 02 6d 08   .....C........m.
0010 - 92 99 30 4d 06 c4 e1 39-18 48 f8 24 bd a6 7e e0   ..0M...9.H.$..~.
0020 - 3d c3 7a 59 1d ff 70 a6-2e 8b 5d c9 c6 3d 38 cb   =.zY..p...]..=8.
0030 - aa f7 4a d6 1b 24 54 c4-9f 4f 74 b4 52 2b 9a 89   ..J..$T..Ot.R+..
0040 - 3b 72 d8 ce 60 fa dc 72-36 9d 0a 31 45 32 54 94   ;r..`..r6..1E2T.
0050 - 61 c4 9e 05 32 68 08 d8-d8 41 e3 0c d5 b3 81 13   a...2h...A......
0060 - ec 5c 95 c5 23 a7 71 a3-0d c0 e6 13 04 14 db 6c   .\..#.q........l
0070 - 9d f2 10 e0 52 ff 44 be-a9 c4 8a 8e ee 13 3f 4e   ....R.D.......?N
0080 - a1 3e 04 72 ea 35 5f 42-04 e7 aa b0 82 df c1 07   .>.r.5_B........
0090 - a6 db 7d d5 81 b7 33 cf-a9 bc 95 76 63 ae 9b 7a   ..}...3....vc..z
00a0 - f9 11 79 c0 31 8d e0 53-11 e6 34 3d a9 a6 53 9c   ..y.1..S..4=..S.
00b0 - 90 a6 68 da 0a 94 05 b3-0e 79 be a6 8b 82 4c 27   ..h......y....L'
00c0 - 76 3e 76 59 81 db dd dd-27 c4 ea cd b1 d9 b1 86   v>vY....'.......
00d0 - e3 7b f0 9a 7c d5 3c aa-ae a1 8d f0 96 73 2c 96   .{..|.<......s,.
00e0 - 53 01 4e 49 2e 4b ed 86-cd 98 60 99 8b 5a 21 c5   S.NI.K....`..Z!.
00f0 - 1a e6 b7 1d 45 8f d1 bf-83 f9 bc e6 46 14 7e c3   ....E.......F.~.
wJi8zuBDsQbeiP/C8gJtCJKZME0GxOE5GEj4JL2mfuA9w3pZHf9wpi6LXcnGPTjLqvdK1hskVMSfT3S0UiuaiTty2M5g+txyNp0KMUUyVJRhxJ4FMmgI2NhB4wzVs4ET7FyVxSOncaMNwOYTBBTbbJ3yEOBS/0S+qcSKju4TP06hPgRy6jVfQgTnqrCC38EHptt91YG3M8+pvJV2Y66bevkRecAxjeBTEeY0PammU5yQpmjaCpQFsw55vqaLgkwndj52WYHb3d0nxOrNsdmxhuN78Jp81TyqrqGN8JZzLJZTAU5JLkvths2YYJmLWiHFGua3HUWP0b+D+bzmRhR+ww==

The above shows the 256 bytes in the console dump as representing the number in big-endian binary form. That is the data that is base64 encoded and produces final line of output. The code should look very familiar, as it is basically identical to the first sample in this answer; only the source of data is different.

I suspect this is what you will need eventually, though you're posted code suggests you're already starting with a bignum, so the beginning of the above code that creates a bignum from the string is already done.


来源: stackexchange

问:
How to store info from an Array to an Array Object?
I have a Java class which uses BufferedReader to obtain information from a text file, then store the information into an Array called newData . I want to store a certain part of the information to the VegTypes[f] = new VegType(); but I not sure what code should I write here to obtain that part of information.

Without completing this part, I am not able to continue working on another Array Object which is Vegs[i] = new Veg(newData[0], newData[1], newData[2],); for storing information together with VegTypes Array Object.

Below is my code of the Java class:

```<code>public class theVegetable {

    private Veg[] Vegs;
    private VegType[] VegTypes;

    public theVegetable() {
        int quantity;
        int vegQuantity;
        String vegLine;

        try {

            BufferedReader br = new BufferedReader(new FileReader("vegetableInfo.txt"));
            quantity = Integer.parseInt(vegLine.readLine());

            Vegs = new Veg[quantity];

            for (int i = 0; i < quantity; i++) {
               vegLine = br.readLine();
                String[] newData = vegLine.split(";");

                vegQuantity = Integer.parseInt(newData[3]);

                //For loop to store information into VegTypes
                for (int f = 0; j < vegQuantity; f++) {

                    VegTypes[f] = new VegType();

                }

                //Vegs Array Object to store information plus VegTypes
                Vegs[i] = new Veg(newData[0], newData[1], newData[2],);

            }

            br.close();

        } catch (FileNotFoundException e) {
            System.out.println("File not found.");
        }
    }
}
</code>```

Below is my vegetableInfo.txt text file:

```<code>3
Tomato;class1;Malaysia Tomato;2;MT100A;MT1;200;90;MT20A;MT2;600;80;Malaysia product
Avocado;class2;Europe Avocado;4;EA100A;EA1;300;90;EA14A;EA2;90;80;EA230A;EA3;43;50.9;EA470A;EA4;400;76;Europe product
Cabbage;class3;Malaysia Cabbage;3;MC100A;MC1;500;20;MC49A;MC2;500;50;MC800A;MC3;600;10.3;Malaysia product
</code>```

The number 3 at the top of the text file is for the int quantity; variable to store the amount.
The kind of information I want the VegTypes[f] = new VegType(); to store are MT100A;MT1;200;90;MT20A;MT2;600;80;, the number 2 besides the Malaysia Tomato are for int vegQuantity; variable. Same thing goes for other vegetables in the text file.

Constructor of my private VegType[] VegTypes; Array Object:

```<code>private String vegCode;
private String vegBatch;
private int vegBatchQuantity;
private double vegGrade;

    public VegType(String inVegCode, String inVegBatch, int inVegBatchQuantity, double inVegGrade) {
        vegCode = inVegCode;
        vegBatch = inVegBatch;
        vegBatchQuantity = inVegBatchQuantity;
        vegGrade = inVegGrade;
    }
</code>```

My Veg Class:

```<code>public class Veg {

    private String vegetableName;
    private String classLevel;
    private String productionCountry;
    private VegType[] VegTypes;
    private String productType;

    //Constructor
    public Veg(String inVegetableName, String inClassLevel, String inProductionCountry, VegType[] inVegTypes, String inProductType) {
        vegetableName = inVegetableName;
        classLevel = inClassLevel;
        productionCountry = inProductionCountry;
        vegType = inVegTypes;

        productType = inProductType;
    }

    public String getVegetableName() {
        return vegetableName;
    }

    public String getClassLevel() {
        return classLevel;
    }

    public String getProductionCountry() {
        return productionCountry;
    }

    public String getProductType() {
        return productType;
    }
}
</code>```

答:
This is wrong:

```<code>                //For loop to store information into VegTypes
                for (int f = 0; j < vegQuantity; f++) {

                    VegTypes[f] = new VegType();

                }
</code>```

you need to use f to adjust the index into your array of fields.

```<code>                for (int f = 0; j < vegQuantity; f++) {
                    String vegCode = newLine[f*4 + 4];
                    String vegBatch = newLine[f*4 + 5];
                    int vegQuantity = Integer.parse(newLine[f*4 + 6]);
                    double vegGrade = Double.parse(newLine[f*4 + 7]);

                    VegTypes[f] = new VegType(vegCode, vegBatch, vegQuantity, vegGrade);

                }

</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have a Java class which uses BufferedReader to obtain information from a text file, then store the information into an Array called newData . I want to store a certain part of the information to the VegTypes[f] = new VegType(); but I not sure what code should I write here to obtain that part of information.

Without completing this part, I am not able to continue working on another Array Object which is Vegs[i] = new Veg(newData[0], newData[1], newData[2],); for storing information together with VegTypes Array Object.

Below is my code of the Java class:

public class theVegetable {

    private Veg[] Vegs;
    private VegType[] VegTypes;

    public theVegetable() {
        int quantity;
        int vegQuantity;
        String vegLine;

        try {

            BufferedReader br = new BufferedReader(new FileReader("vegetableInfo.txt"));
            quantity = Integer.parseInt(vegLine.readLine());

            Vegs = new Veg[quantity];

            for (int i = 0; i < quantity; i++) {
               vegLine = br.readLine();
                String[] newData = vegLine.split(";");

                vegQuantity = Integer.parseInt(newData[3]);

                //For loop to store information into VegTypes
                for (int f = 0; j < vegQuantity; f++) {

                    VegTypes[f] = new VegType();

                }

                //Vegs Array Object to store information plus VegTypes
                Vegs[i] = new Veg(newData[0], newData[1], newData[2],);

            }

            br.close();

        } catch (FileNotFoundException e) {
            System.out.println("File not found.");
        }
    }
}

Below is my vegetableInfo.txt text file:

3
Tomato;class1;Malaysia Tomato;2;MT100A;MT1;200;90;MT20A;MT2;600;80;Malaysia product
Avocado;class2;Europe Avocado;4;EA100A;EA1;300;90;EA14A;EA2;90;80;EA230A;EA3;43;50.9;EA470A;EA4;400;76;Europe product
Cabbage;class3;Malaysia Cabbage;3;MC100A;MC1;500;20;MC49A;MC2;500;50;MC800A;MC3;600;10.3;Malaysia product

The number 3 at the top of the text file is for the int quantity; variable to store the amount.
The kind of information I want the VegTypes[f] = new VegType(); to store are MT100A;MT1;200;90;MT20A;MT2;600;80;, the number 2 besides the Malaysia Tomato are for int vegQuantity; variable. Same thing goes for other vegetables in the text file.

Constructor of my private VegType[] VegTypes; Array Object:

private String vegCode;
private String vegBatch;
private int vegBatchQuantity;
private double vegGrade;

    public VegType(String inVegCode, String inVegBatch, int inVegBatchQuantity, double inVegGrade) {
        vegCode = inVegCode;
        vegBatch = inVegBatch;
        vegBatchQuantity = inVegBatchQuantity;
        vegGrade = inVegGrade;
    }

My Veg Class:

public class Veg {

    private String vegetableName;
    private String classLevel;
    private String productionCountry;
    private VegType[] VegTypes;
    private String productType;

    //Constructor
    public Veg(String inVegetableName, String inClassLevel, String inProductionCountry, VegType[] inVegTypes, String inProductType) {
        vegetableName = inVegetableName;
        classLevel = inClassLevel;
        productionCountry = inProductionCountry;
        vegType = inVegTypes;

        productType = inProductType;
    }

    public String getVegetableName() {
        return vegetableName;
    }

    public String getClassLevel() {
        return classLevel;
    }

    public String getProductionCountry() {
        return productionCountry;
    }

    public String getProductType() {
        return productType;
    }
}

Body:
This is wrong:

                //For loop to store information into VegTypes
                for (int f = 0; j < vegQuantity; f++) {

                    VegTypes[f] = new VegType();

                }

you need to use f to adjust the index into your array of fields.

                for (int f = 0; j < vegQuantity; f++) {
                    String vegCode = newLine[f*4 + 4];
                    String vegBatch = newLine[f*4 + 5];
                    int vegQuantity = Integer.parse(newLine[f*4 + 6]);
                    double vegGrade = Double.parse(newLine[f*4 + 7]);

                    VegTypes[f] = new VegType(vegCode, vegBatch, vegQuantity, vegGrade);

                }


问:
How does "apt-get install" work to download a file?
I have recently started using Ubuntu and am confused as to how the Linux package system is run and operated. Does a company (i.e. Canonical or Azure (if you are using WSL)) own and run the package installing servers, or is it community-based like a torrent if you know what I mean? I can imagine the server resources would be very expensive.</p>

答:
There is an archive for Ubuntu packages located at https://packages.ubuntu.com/.
Normally you can see the sources you are currently using in the file /etc/apt/sources.list as described in the official manual.


问:
Can we render .ejs file using flask?
I am currently learning flask framework after completing my node.js and express. I just want to know can we render .ejs file also in flask as we can do in node js.</p>

答:
As far as I can tell there is no Python library capable of rendering .ejs (Embeddable JavaScript Template) files. This is most likely because of the fact that ejs files permit a lot of JavaScript syntax (if not arbitrary JavaScript). So implementing that within Python would be a pain. However there are a ton of templating languages with Python support (see this page on the Python wiki for a list). That said, you could theoretically just execute ejs as a separate process:

```<code>import json
import subprocess

from flask import Flask
app = Flask("app")

data = {
  "title": "Example",
  "user": { "firstName": "World" },
  "messages": [ "foo", "bar", "baz" ]
}

@app.route("/")
def hello_world():
  # Note: this assumes you have globally installed ejs with: npm install -g ejs
  ejsRenderer = subprocess.Popen(
    ["ejs", "example.ejs"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  rendered = ejsRenderer.communicate(bytes(json.dumps(data), "utf8"))[0]
  ejsRenderer.stdin.close()
  ejsRenderer.wait()
  return rendered

app.run(host="0.0.0.0", port=8080)
</code>```

Title: Can we render .ejs file using flask?

Body:
As far as I can tell there is no Python library capable of rendering .ejs (Embeddable JavaScript Template) files. This is most likely because of the fact that ejs files permit a lot of JavaScript syntax (if not arbitrary JavaScript). So implementing that within Python would be a pain. However there are a ton of templating languages with Python support (see this page on the Python wiki for a list). That said, you could theoretically just execute ejs as a separate process:

import json
import subprocess

from flask import Flask
app = Flask("app")

data = {
  "title": "Example",
  "user": { "firstName": "World" },
  "messages": [ "foo", "bar", "baz" ]
}

@app.route("/")
def hello_world():
  # Note: this assumes you have globally installed ejs with: npm install -g ejs
  ejsRenderer = subprocess.Popen(
    ["ejs", "example.ejs"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
  rendered = ejsRenderer.communicate(bytes(json.dumps(data), "utf8"))[0]
  ejsRenderer.stdin.close()
  ejsRenderer.wait()
  return rendered

app.run(host="0.0.0.0", port=8080)


问:
Incomplete stairway in C
So what I need to have as a finished product is a program that:

Asks for an int and only continues if the given is between one and eight. (Finished)

When given the number "8" a stairway that has eight hashtags in it's bottom row must appear. (Finished)

The stairway must be right-aligned, so there must be spaces printed to make the top right hashtag align with the bottom right hashtag. (Incomplete)

When the stairway is given the number "1" it must simply print a single hastag. (Incomplete)

My code is as follows:

```<code>int main (void)
{
    int height = 0;
    int change;
    int row;
    int space;

    do{
        height = get_int("Height: ");
    } while(height < 1  || height > 8);

    for (change = 0; change < height; change++ )
    {
        for (space = 7; space > change; space--)
        {
            printf(" ");
        }

        for (row = -1; row < change; row++)
        {
            printf("#");
        }

        printf("\n");
    }
}
</code>```

PLease can someone tell my which functions I need to implement so I can complete the final two criteria?

答:
Change the starting value of space so it depends on the height, so you don't print more spaces than needed.

```<code>        for (space = height-1; space > change; space--)
        {
            printf(" ");
        }
</code>```

Title: Incomplete stairway in C

Body:
So what I need to have as a finished product is a program that:

Asks for an int and only continues if the given is between one and eight. (Finished)

When given the number "8" a stairway that has eight hashtags in it's bottom row must appear. (Finished)

The stairway must be right-aligned, so there must be spaces printed to make the top right hashtag align with the bottom right hashtag. (Incomplete)

When the stairway is given the number "1" it must simply print a single hastag. (Incomplete)

My code is as follows:

int main (void)
{
    int height = 0;
    int change;
    int row;
    int space;

    do{
        height = get_int("Height: ");
    } while(height < 1  || height > 8);

    for (change = 0; change < height; change++ )
    {
        for (space = 7; space > change; space--)
        {
            printf(" ");
        }

        for (row = -1; row < change; row++)
        {
            printf("#");
        }

        printf("\n");
    }
}

PLease can someone tell my which functions I need to implement so I can complete the final two criteria?

Body:
Change the starting value of space so it depends on the height, so you don't print more spaces than needed.

        for (space = height-1; space > change; space--)
        {
            printf(" ");
        }


问:
React: Re-render sets state to initial value even after calling setState
I am new to React and this is my first time asking a question on StackOverFlow so my apologies if my question is lame or if i missed some post guildelines.

I get the value for the setState in a function which is passed as a prop to child component:

const [textAreaValue, setTextAreaValue] = useState(null);

const handleTextAreaChange = (newTextAreaValue) => {
        return setTextAreaValue(newTextAreaValue);
    };
  ```
</div>
</div>
</p>
<p>The textAreaValue isn't updated immediately, which is understandable considering React schedules such requests.</p>
<p>I have another function called textFile(), which is triggered when a user clicks a button.</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code>const TextFile = (value) => {
        const element = document.createElement("a");
        console.log(textAreaValue);// outputs null
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };</code>```

As seen in the comment the state update isn't reflected.

To know if the state change happens, i setup a useEffect, and logged the value of textAreaValue and it does show the updated value.

So my guess is, whenever the state is re-rendered, the state value is set to the initial value, that is null.
I am scratching my head here, i would really like to know what is happening here and how i can resolve this issue.

Here's the complete code:

import React, { useEffect, useState } from "react";

import JoditEditor from "../../src/";

const From = () => {
    const [config, setConfig] = useState({
        readonly: false,
        toolbar: true,
        extraButtons: [
            {
                name: "Save to file",
                icon: "fa fa-superscript",
                mode: 3,
                exec: function (a, b, c, d) {
                    debugger;
                    TextFile();
                },
            },
        ],
    });

    const [textAreaValue, setTextAreaValue] = useState(null);
    const _setTextAreaValue = (textval) => {
        setTextAreaValue(textval);
        setTextAreaValue((state) => {
            console.log("after setstate", state); // correct update value;
            return state;
        });
    };
    useEffect(() => {
        //debugger;
        console.log("inside use effect");
        console.log(textAreaValue);
    });

    const TextFile = () => {
        const element = document.createElement("a");
        console.log("inside writetotext", textAreaValue);
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };

    const handleBlurAreaChange = (areaValue, event) => {
        console.log("before handleBlurAreaChange", textAreaValue, event); //null
        _setTextAreaValue(areaValue);
        console.log("after handleBlurAreaChange", textAreaValue); //null
    };

    const handleTextAreaChange = (newTextAreaValue) => {
        //debugger;
        console.log("before handleTextAreaChange", textAreaValue); //null
        _setTextAreaValue(newTextAreaValue);
        console.log(" after handleTextAreaChange", textAreaValue); //null
        return;
    };

    return (

            <JoditEditor
                config={config}
                onChange={handleTextAreaChange}
                onBlur={handleBlurAreaChange}
                value={textAreaValue}
            />

    );
};

export default From;```

答:
For the parameter inside the function below:

```<code>const _setTextAreaValue = (textval)
</code>```

Can you try to change it as below:

```<code>const _setTextAreaValue = (e) => {
setTextAreaValue(e.target.value)
console.log(textAreaValue)
}
</code>```

Body:
I am new to React and this is my first time asking a question on StackOverFlow so my apologies if my question is lame or if i missed some post guildelines.

I get the value for the setState in a function which is passed as a prop to child component:

const [textAreaValue, setTextAreaValue] = useState(null);

const handleTextAreaChange = (newTextAreaValue) => {
        return setTextAreaValue(newTextAreaValue);
    };

The textAreaValue isn't updated immediately, which is understandable considering React schedules such requests.

I have another function called textFile(), which is triggered when a user clicks a button.

const TextFile = (value) => {
        const element = document.createElement("a");
        console.log(textAreaValue);// outputs null
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };

As seen in the comment the state update isn't reflected.

To know if the state change happens, i setup a useEffect, and logged the value of textAreaValue and it does show the updated value.

So my guess is, whenever the state is re-rendered, the state value is set to the initial value, that is null.
I am scratching my head here, i would really like to know what is happening here and how i can resolve this issue.

Here's the complete code:

import React, { useEffect, useState } from "react";

import JoditEditor from "../../src/";

const From = () => {
    const [config, setConfig] = useState({
        readonly: false,
        toolbar: true,
        extraButtons: [
            {
                name: "Save to file",
                icon: "fa fa-superscript",
                mode: 3,
                exec: function (a, b, c, d) {
                    debugger;
                    TextFile();
                },
            },
        ],
    });

    const [textAreaValue, setTextAreaValue] = useState(null);
    const _setTextAreaValue = (textval) => {
        setTextAreaValue(textval);
        setTextAreaValue((state) => {
            console.log("after setstate", state); // correct update value;
            return state;
        });
    };
    useEffect(() => {
        //debugger;
        console.log("inside use effect");
        console.log(textAreaValue);
    });

    const TextFile = () => {
        const element = document.createElement("a");
        console.log("inside writetotext", textAreaValue);
        const file = new Blob([textAreaValue], {
            type: "text/html",
        });
        element.href = URL.createObjectURL(file);
        element.download = "myFile.html";
        document.body.appendChild(element);
        element.click();
    };

    const handleBlurAreaChange = (areaValue, event) => {
        console.log("before handleBlurAreaChange", textAreaValue, event); //null
        _setTextAreaValue(areaValue);
        console.log("after handleBlurAreaChange", textAreaValue); //null
    };

    const handleTextAreaChange = (newTextAreaValue) => {
        //debugger;
        console.log("before handleTextAreaChange", textAreaValue); //null
        _setTextAreaValue(newTextAreaValue);
        console.log(" after handleTextAreaChange", textAreaValue); //null
        return;
    };

    return (

            <JoditEditor
                config={config}
                onChange={handleTextAreaChange}
                onBlur={handleBlurAreaChange}
                value={textAreaValue}
            />

    );
};

export default From;

Body:
For the parameter inside the function below:

const _setTextAreaValue = (textval)

Can you try to change it as below:

const _setTextAreaValue = (e) => {
setTextAreaValue(e.target.value)
console.log(textAreaValue)
}


问:
Cocoa: Youtube video does not support full screen in WKWebview
I’m making a web browser using Xcode, I played with the browser then relized the it dosn’t play full screen youtube video’s and embeded videos. I have tried this code...

```<code>let webViewConfiguration = WKWebViewConfiguration()
webViewConfiguration.allowsInlineMediaPlayback = false
WKWebView(frame: .zero, configuration: webViewConfiguration)
</code>```

But it says Wkwebview has no member of allowsInlineMediaPlayback. This is an image of what youtube shows

Here is my code for more detail…

```<code>import Cocoa
import WebKit

class ViewController: NSViewController, WKUIDelegate, NSSharingServicePickerDelegate, WKNavigationDelegate {
    let kAlreadyBeenLaunched = "AlreadyBeenLaunched"
    // MARK: - Outlets
    @IBOutlet weak var messengerView: NSView!

    @IBOutlet weak var googleBookMarkOut: NSButton!
    @IBOutlet weak var googleSearchField: NSSearchField!
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var sideBar: NSBox!
    @IBOutlet weak var searchBar: NSBox!
    @IBOutlet weak var webBox: NSBox!
    // MARK: - View Did Load
    override func viewDidLoad() {
        super.viewDidLoad()

        self.webView.configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
        self.webView.navigationDelegate = self
        let myURL = URL(string: "https://www.google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

        //When user first opens app
        if !UserDefaults.standard.bool(forKey: kAlreadyBeenLaunched) {
            UserDefaults.standard.setValue(NSNumber(value: true), forKey: kAlreadyBeenLaunched)
            //What users will see when they enter this app the first time
            sideBar.borderColor = .clear
            searchBar.borderColor = .clear
            webBox.borderColor = .clear
        }
    }
    override func viewDidAppear() {
        self.webView.configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
    }
    // MARK: - Useless
    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }
    // MARK: - Webview
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }

    // MARK: - Side Bar Buttons
    @IBAction func homegoole(_ sender: Any) {
        let myURL = URL(string: "https://www.google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
        self.view.window?.tab.title = webView.title!
    }
    @IBAction func shareButton(_ sender: Any) {
        let ShareURL = webView.url
        let sharingpicker = NSSharingServicePicker(items: [ShareURL as Any])
        sharingpicker.delegate = self
        sharingpicker.show(relativeTo: NSZeroRect, of: sender as! NSView, preferredEdge: .minY)
    }
    @IBAction func googleBookMark(_ sender: Any) {
        let helealo = URL(string:"https://www.google.com/bookmarks/")
        let helleago1 = URLRequest(url: helealo!)
        webView.load(helleago1)
    }
    @IBAction func refreshButton(_ sender: Any) {
        webView.reload()
    }
    // MARK: - Colour Buttons
    @IBAction func themePink(_ sender: Any) {
        sideBar.borderColor = .systemPink
        searchBar.borderColor = .systemPink
        webBox.borderColor = .systemPink
    }
    @IBAction func themeRed(_ sender: Any) {
        sideBar.borderColor = .systemRed
        searchBar.borderColor = .systemRed
        webBox.borderColor = .systemRed
    }
    @IBAction func themeOrange(_ sender: Any) {
        sideBar.borderColor = .systemOrange
        searchBar.borderColor = .systemOrange
        webBox.borderColor = .systemOrange
    }
    @IBAction func themeYellow(_ sender: Any) {
        sideBar.borderColor = .systemYellow
        searchBar.borderColor = .systemYellow
        webBox.borderColor = .systemYellow
    }
    @IBAction func themeGrey(_ sender: Any) {
        sideBar.borderColor = .systemGray
        searchBar.borderColor = .systemGray
        webBox.borderColor = .systemGray
    }
    @IBAction func themePurple(_ sender: Any) {
        sideBar.borderColor = .systemPurple
        searchBar.borderColor = .systemPurple
        webBox.borderColor = .systemPurple
    }
    @IBAction func themeBlue(_ sender: Any) {
        sideBar.borderColor = .blue
        searchBar.borderColor = .blue
        webBox.borderColor = .blue
    }
    @IBAction func lightBlue(_ sender: Any) {sideBar.borderColor = .systemBlue
        searchBar.borderColor = .systemBlue
        webBox.borderColor = .systemBlue
    }
    @IBAction func themeTorquise(_ sender: Any) {
        sideBar.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
        searchBar.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
        webBox.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
    }
    @IBAction func themeGreen(_ sender: Any) {
        sideBar.borderColor = .systemGreen
        searchBar.borderColor = .systemGreen
        webBox.borderColor = .systemGreen
    }
    // MARK: - Side Bar Button
    @IBAction func showTitle(_ sender: Any) {
        self.view.window?.tab.title = webView.title!
        self.view.window?.title = webView.title!
    }
    // MARK: - Google/URL searche
    @IBAction func urlSearche(_ sender: Any) {
        let urlStr = googleSearchField.stringValue
        if urlStr.hasPrefix("https://") {
            let url = NSURL(string: urlStr)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if urlStr.hasPrefix("http://") {
            let url = NSURL(string: urlStr)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        }
        else if urlStr.hasPrefix("www."){
            let urlWithOUTHTPPS = "https://" + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".com") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".ca") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".org") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".net") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".int") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".edu") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".gov") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".mil") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else {
            let textToSearch = googleSearchField.stringValue
            let allowedCharacters = NSCharacterSet.urlFragmentAllowed
            guard let  encodedSearchString  = textToSearch.addingPercentEncoding(withAllowedCharacters: allowedCharacters)  else { return }
            let queryString = "https://www.google.de/search?q=\(encodedSearchString)"
            guard let queryURL = URL(string: queryString) else { return }
            let myRequest = URLRequest(url:queryURL)
            webView.load(myRequest)
        }
    }
    @IBAction func googleBookMarks(_ sender: Any) {
        let myURL = URL(string: "https://www.google.com/bookmarks")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
    override func keyDown(with event: NSEvent) {

        if event.keyCode == 35 {

        }

    }
    @IBAction func messengerButton(_ sender: Any) {

        messengerView.isHidden = false

    }
}
</code>```

Is there any way I can make full screen videos in Wkwebview?

答:
allowsInlineMediaPlayback is not available for macOS, it is only available for

iOS 8.0+

Mac Catalyst 13.0+

Body:
I’m making a web browser using Xcode, I played with the browser then relized the it dosn’t play full screen youtube video’s and embeded videos. I have tried this code...

let webViewConfiguration = WKWebViewConfiguration()
webViewConfiguration.allowsInlineMediaPlayback = false
WKWebView(frame: .zero, configuration: webViewConfiguration)

But it says Wkwebview has no member of allowsInlineMediaPlayback. This is an image of what youtube shows

Here is my code for more detail…

import Cocoa
import WebKit

class ViewController: NSViewController, WKUIDelegate, NSSharingServicePickerDelegate, WKNavigationDelegate {
    let kAlreadyBeenLaunched = "AlreadyBeenLaunched"
    // MARK: - Outlets
    @IBOutlet weak var messengerView: NSView!

    @IBOutlet weak var googleBookMarkOut: NSButton!
    @IBOutlet weak var googleSearchField: NSSearchField!
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var sideBar: NSBox!
    @IBOutlet weak var searchBar: NSBox!
    @IBOutlet weak var webBox: NSBox!
    // MARK: - View Did Load
    override func viewDidLoad() {
        super.viewDidLoad()

        self.webView.configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
        self.webView.navigationDelegate = self
        let myURL = URL(string: "https://www.google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)

        //When user first opens app
        if !UserDefaults.standard.bool(forKey: kAlreadyBeenLaunched) {
            UserDefaults.standard.setValue(NSNumber(value: true), forKey: kAlreadyBeenLaunched)
            //What users will see when they enter this app the first time
            sideBar.borderColor = .clear
            searchBar.borderColor = .clear
            webBox.borderColor = .clear
        }
    }
    override func viewDidAppear() {
        self.webView.configuration.preferences.setValue(true, forKey: "developerExtrasEnabled")
    }
    // MARK: - Useless
    override var representedObject: Any? {
        didSet {
            // Update the view, if already loaded.
        }
    }
    // MARK: - Webview
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if navigationAction.targetFrame == nil {
            webView.load(navigationAction.request)
        }
        return nil
    }

    // MARK: - Side Bar Buttons
    @IBAction func homegoole(_ sender: Any) {
        let myURL = URL(string: "https://www.google.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
        self.view.window?.tab.title = webView.title!
    }
    @IBAction func shareButton(_ sender: Any) {
        let ShareURL = webView.url
        let sharingpicker = NSSharingServicePicker(items: [ShareURL as Any])
        sharingpicker.delegate = self
        sharingpicker.show(relativeTo: NSZeroRect, of: sender as! NSView, preferredEdge: .minY)
    }
    @IBAction func googleBookMark(_ sender: Any) {
        let helealo = URL(string:"https://www.google.com/bookmarks/")
        let helleago1 = URLRequest(url: helealo!)
        webView.load(helleago1)
    }
    @IBAction func refreshButton(_ sender: Any) {
        webView.reload()
    }
    // MARK: - Colour Buttons
    @IBAction func themePink(_ sender: Any) {
        sideBar.borderColor = .systemPink
        searchBar.borderColor = .systemPink
        webBox.borderColor = .systemPink
    }
    @IBAction func themeRed(_ sender: Any) {
        sideBar.borderColor = .systemRed
        searchBar.borderColor = .systemRed
        webBox.borderColor = .systemRed
    }
    @IBAction func themeOrange(_ sender: Any) {
        sideBar.borderColor = .systemOrange
        searchBar.borderColor = .systemOrange
        webBox.borderColor = .systemOrange
    }
    @IBAction func themeYellow(_ sender: Any) {
        sideBar.borderColor = .systemYellow
        searchBar.borderColor = .systemYellow
        webBox.borderColor = .systemYellow
    }
    @IBAction func themeGrey(_ sender: Any) {
        sideBar.borderColor = .systemGray
        searchBar.borderColor = .systemGray
        webBox.borderColor = .systemGray
    }
    @IBAction func themePurple(_ sender: Any) {
        sideBar.borderColor = .systemPurple
        searchBar.borderColor = .systemPurple
        webBox.borderColor = .systemPurple
    }
    @IBAction func themeBlue(_ sender: Any) {
        sideBar.borderColor = .blue
        searchBar.borderColor = .blue
        webBox.borderColor = .blue
    }
    @IBAction func lightBlue(_ sender: Any) {sideBar.borderColor = .systemBlue
        searchBar.borderColor = .systemBlue
        webBox.borderColor = .systemBlue
    }
    @IBAction func themeTorquise(_ sender: Any) {
        sideBar.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
        searchBar.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
        webBox.borderColor = .init(red: 44/255, green: 192/255.0, blue: 210/255, alpha: 1)
    }
    @IBAction func themeGreen(_ sender: Any) {
        sideBar.borderColor = .systemGreen
        searchBar.borderColor = .systemGreen
        webBox.borderColor = .systemGreen
    }
    // MARK: - Side Bar Button
    @IBAction func showTitle(_ sender: Any) {
        self.view.window?.tab.title = webView.title!
        self.view.window?.title = webView.title!
    }
    // MARK: - Google/URL searche
    @IBAction func urlSearche(_ sender: Any) {
        let urlStr = googleSearchField.stringValue
        if urlStr.hasPrefix("https://") {
            let url = NSURL(string: urlStr)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if urlStr.hasPrefix("http://") {
            let url = NSURL(string: urlStr)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        }
        else if urlStr.hasPrefix("www."){
            let urlWithOUTHTPPS = "https://" + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".com") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".ca") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".org") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".net") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".int") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".edu") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".gov") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else if  urlStr.hasSuffix(".mil") {
            let urlWithOUTHTPPS = "https://www." + googleSearchField.stringValue
            let url = NSURL(string: urlWithOUTHTPPS)
            let req = NSURLRequest(url:url! as URL)
            self.webView!.load(req as URLRequest)
        } else {
            let textToSearch = googleSearchField.stringValue
            let allowedCharacters = NSCharacterSet.urlFragmentAllowed
            guard let  encodedSearchString  = textToSearch.addingPercentEncoding(withAllowedCharacters: allowedCharacters)  else { return }
            let queryString = "https://www.google.de/search?q=\(encodedSearchString)"
            guard let queryURL = URL(string: queryString) else { return }
            let myRequest = URLRequest(url:queryURL)
            webView.load(myRequest)
        }
    }
    @IBAction func googleBookMarks(_ sender: Any) {
        let myURL = URL(string: "https://www.google.com/bookmarks")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
    override func keyDown(with event: NSEvent) {

        if event.keyCode == 35 {

        }

    }
    @IBAction func messengerButton(_ sender: Any) {

        messengerView.isHidden = false

    }
}

Is there any way I can make full screen videos in Wkwebview?


问:
How does a function know what inputs to draw from when labeled under different names?
How can int length and int array[] be labeled differently than int TOTAL and int scores, yet they are recognized as being the same in the average() function? I assumed they had to be called the same thing in order to be recognized?

```<code>#include <cs50.h>
#include <stdio.h>

float average();

const int TOTAL = 3;

int main(void)
{
    int scores[TOTAL];
    for (int i = 0; i < TOTAL; i++)
        {
        scores[i] = get_int("Score: ");
        }

    printf("Average: %f\n", average(TOTAL, scores));

}

//int array [] same as saying int scores [] ?
//int 'length' same as saying 'TOTAL' ?
float average(int length, int array[])
{
    int sum = 0;
    for (int i = 0; i < length; i++)
    {
        sum += array[i];
    }
    return sum / (float) length;
}
</code>```

答:
Variable names in most programming languages have a certain "scope" that they apply to. In C/C++, scopes are often determined by regions between a { and } character, e.g. a function scope or a loop scope within it.

In this specific example, TOTAL is defined in the "global" scope. Anything after that line can see and access that variable. This is generally considered bad practice, because it "pollutes" the global scope. Imagine, what would happen if you added someone else's code that also defined TOTAL to be something else? Or worse, forgot to define it but used it anyway? Nothing good, I promise you.

All other variables in this example are defined in their own "local" scope. The name scores is usable int main(void) { int scores... <HERE> } <but not here>. Likewise, the name array is usable average(int length, int array[]) { <HERE> } <but not here>.

But how do you get data from one function to another? You call the function! From main, when you call average(TOTAL, scores), you are referring to the name TOTAL from the global scope, and scores from main's scope, and passing them as "arguments" or "parameters" to the function average. The function average defines its own names for those arguments, but they will still contain the data from the variables used where it is called.

This is an essential property of most programming languages. Without it, function callers would need to make sure their names don't conflict with the internal ones used by the functions they call, and vice-versa. The relevance of this mechanism might be more obvious with a different example:

```<code>// convert a temperature in celcius to farenheit
float c2f(float celcius) {
  return 1.8f * celcius + 32.0f;
}

// print the computer temperature sensor values in farenheit
void print_computer_temperatures(temperatures_t temps) {
  float gpu_temp = c2f(temps.gpu);
  float cpu_temp = c2f(temps.cpu);
  float chipset_temp = c2f(sys()->GetTemp(CHIPSET));
  float chassis_temp_c = -1;
  CoolerMasterQueryChassisTemp(&chassis_temp_c);
  float chassis_temp = c2f(chassis_temp_c);
  printf(...);
}
</code>```

Body:
How can int length and int array[] be labeled differently than int TOTAL and int scores, yet they are recognized as being the same in the average() function? I assumed they had to be called the same thing in order to be recognized?

#include <cs50.h>
#include <stdio.h>

float average();

const int TOTAL = 3;

int main(void)
{
    int scores[TOTAL];
    for (int i = 0; i < TOTAL; i++)
        {
        scores[i] = get_int("Score: ");
        }

    printf("Average: %f\n", average(TOTAL, scores));

}

//int array [] same as saying int scores [] ?
//int 'length' same as saying 'TOTAL' ?
float average(int length, int array[])
{
    int sum = 0;
    for (int i = 0; i < length; i++)
    {
        sum += array[i];
    }
    return sum / (float) length;
}

Body:
Variable names in most programming languages have a certain "scope" that they apply to. In C/C++, scopes are often determined by regions between a { and } character, e.g. a function scope or a loop scope within it.

In this specific example, TOTAL is defined in the "global" scope. Anything after that line can see and access that variable. This is generally considered bad practice, because it "pollutes" the global scope. Imagine, what would happen if you added someone else's code that also defined TOTAL to be something else? Or worse, forgot to define it but used it anyway? Nothing good, I promise you.

All other variables in this example are defined in their own "local" scope. The name scores is usable int main(void) { int scores... <HERE> } <but not here>. Likewise, the name array is usable average(int length, int array[]) { <HERE> } <but not here>.

But how do you get data from one function to another? You call the function! From main, when you call average(TOTAL, scores), you are referring to the name TOTAL from the global scope, and scores from main's scope, and passing them as "arguments" or "parameters" to the function average. The function average defines its own names for those arguments, but they will still contain the data from the variables used where it is called.

This is an essential property of most programming languages. Without it, function callers would need to make sure their names don't conflict with the internal ones used by the functions they call, and vice-versa. The relevance of this mechanism might be more obvious with a different example:

// convert a temperature in celcius to farenheit
float c2f(float celcius) {
  return 1.8f * celcius + 32.0f;
}

// print the computer temperature sensor values in farenheit
void print_computer_temperatures(temperatures_t temps) {
  float gpu_temp = c2f(temps.gpu);
  float cpu_temp = c2f(temps.cpu);
  float chipset_temp = c2f(sys()->GetTemp(CHIPSET));
  float chassis_temp_c = -1;
  CoolerMasterQueryChassisTemp(&chassis_temp_c);
  float chassis_temp = c2f(chassis_temp_c);
  printf(...);
}


问:
How can I return only what's inside my
 tag if someone makes a cURL or wget request to my link?
I have a simple "hello world" python script here

print("Hello World")

I uploaded it to my site (similar to Pastebin or GitHub gist)

https://www.bunlongheng.com/raw/YWFjOGMxYTktM2Y5Mi00ZDdlLWI1NWQtOTg0Y2EwYjVlMDM5

When I shared the link, I can see the icon, and the title field as the actual text, it's nice. Tested in iPhone below

When I curl the link, I got <title> & <link> tags come with it like this:

```<code><title>print("Hello World")</title><link rel="shortcut icon" href="https://i.imgur.com/yRk5mqb.png" />```print("Hello World")```
</code>```

Which of course will break if I remotely executed my codes like this

```<code>curl https://www.bunlongheng.com/raw/YWFjOGMxYTktM2Y5Mi00ZDdlLWI1NWQtOTg0Y2EwYjVlMDM5 | python

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   153    0   153    0     0    354      0 --:--:-- --:--:-- --:--:--   353
  File "<stdin>", line 1
    <title>print("Hello World")</title><link rel="shortcut icon" href="https://i.imgur.com/yRk5mqb.png" />```print("Hello World")```
    ^
SyntaxError: invalid syntax
</code>```

How can I return only what's inside my ``` tag if someone makes a cURL or wget to my link?

答:
For PHP

I ended up do this

$userAgent = $_SERVER['HTTP_USER_AGENT'];
if (stripos($userAgent, 'curl') !== false || stripos($userAgent, 'wget') !== false ){
return $paste->raw;
}

```<code>public function raw($uuid)
{
    $paste  = Paste::where('uuid', base64_decode($uuid))->first();

    $userAgent = $_SERVER['HTTP_USER_AGENT'];
    if (stripos($userAgent, 'curl') !== false || stripos($userAgent, 'wget') !== false ){
        return $paste->raw;
    }

    if($paste->type == 'json'){
        return response()->json($paste->data);
    } else {
        $result = htmlentities($paste->raw);
        return '<title>'.$result.'</title><link rel="shortcut icon" href="https://i.imgur.com/WWWynu9.png" />```'.$result.'```';
    }

}
</code>```

Now can I remotely execute bash or python from cURL without an extra HTML tag. The best part is that I don't have to compromise the icon and title for the browser & mobile browser.

Title: How can I return only what's inside my <pre> tag if someone makes a cURL or wget request to my link?

Body:
I have a simple "hello world" python script here

print("Hello World")

I uploaded it to my site (similar to Pastebin or GitHub gist)

https://www.bunlongheng.com/raw/YWFjOGMxYTktM2Y5Mi00ZDdlLWI1NWQtOTg0Y2EwYjVlMDM5

When I shared the link, I can see the icon, and the title field as the actual text, it's nice. Tested in iPhone below

When I curl the link, I got <title> & <link> tags come with it like this:

<title>print("Hello World")</title><link rel="shortcut icon" href="https://i.imgur.com/yRk5mqb.png" />
print("Hello World")

Which of course will break if I remotely executed my codes like this

curl https://www.bunlongheng.com/raw/YWFjOGMxYTktM2Y5Mi00ZDdlLWI1NWQtOTg0Y2EwYjVlMDM5 | python

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   153    0   153    0     0    354      0 --:--:-- --:--:-- --:--:--   353
  File "<stdin>", line 1
    <title>print("Hello World")</title><link rel="shortcut icon" href="https://i.imgur.com/yRk5mqb.png" />
print("Hello World")

    ^
SyntaxError: invalid syntax

How can I return only what's inside my
 tag if someone makes a cURL or wget to my link?

Body:
For PHP

I ended up do this

$userAgent = $_SERVER['HTTP_USER_AGENT'];
if (stripos($userAgent, 'curl') !== false || stripos($userAgent, 'wget') !== false ){
return $paste->raw;
}

public function raw($uuid)
{
    $paste  = Paste::where('uuid', base64_decode($uuid))->first();

    $userAgent = $_SERVER['HTTP_USER_AGENT'];
    if (stripos($userAgent, 'curl') !== false || stripos($userAgent, 'wget') !== false ){
        return $paste->raw;
    }

    if($paste->type == 'json'){
        return response()->json($paste->data);
    } else {
        $result = htmlentities($paste->raw);
        return '<title>'.$result.'</title><link rel="shortcut icon" href="https://i.imgur.com/WWWynu9.png" /><pre>'.$result.'</pre>';
    }

}

Now can I remotely execute bash or python from cURL without an extra HTML tag. The best part is that I don't have to compromise the icon and title for the browser & mobile browser.


问:
How to make image clickable and redirect to its introduction value page in Reactjs
I have called an api then pick let says drinks. i picked drink name and images. Now i need to find the details about that drink.On clicking in this image it show about that . which all these think are present in the api. But i dont know how to do it.

```<code>import React from "react";

const DrinkList = (props) => {

  // const handleTextShow
  return (
    <>
      {props.drinks.map((drink, index) => (
        <div>
          <img
            src={drink.strDrinkThumb}
            alt="drink"
            width="300"
            height="300"
            onClick={handleTextShow}
          ></img>
        </div>
      ))}
    </>
  );
};

export default DrinkList;

</code>```

strDrinkThumb shows photo about that and details be strDetails.

答:
Just pass strDetails to your handleTextShow function

```<code>const DrinkList = (props) => {

    const handleTextShow = (drinkDetail) => {
        console.log(drinkDetail)
    }
    return (
        <>
        {props.drinks.map((drink, index) => (
            <div>
                <img
                    src={drink.strDrinkThumb}
                    alt="drink"
                    width="300"
                    height="300"
                    onClick={() => handleTextShow(drink.strDetails)}
            ></img>
            </div>
        ))}
        </>
    );
};

export default DrinkList;
</code>```

Body:
I have called an api then pick let says drinks. i picked drink name and images. Now i need to find the details about that drink.On clicking in this image it show about that . which all these think are present in the api. But i dont know how to do it.

import React from "react";

const DrinkList = (props) => {

  // const handleTextShow
  return (
    <>
      {props.drinks.map((drink, index) => (

      ))}
    </>
  );
};

export default DrinkList;

strDrinkThumb shows photo about that and details be strDetails.

Body:
Just pass strDetails to your handleTextShow function

const DrinkList = (props) => {

    const handleTextShow = (drinkDetail) => {
        console.log(drinkDetail)
    }
    return (
        <>
        {props.drinks.map((drink, index) => (
            <div>
                <img
                    src={drink.strDrinkThumb}
                    alt="drink"
                    width="300"
                    height="300"
                    onClick={() => handleTextShow(drink.strDetails)}
            ></img>
            </div>
        ))}
        </>
    );
};

export default DrinkList;


问:
Align Image left side and Text right side with css
I have image and a text,i need the image on the left and the text on the right..
i cant change the HTML, so i need to do it with CSS only.</p>

```<code><li>
  <article>
    <header>
      <h3>
        <a href="#">title</a>
      </h3>
    </header>
    <p>
      <img src="image.jpg">
    </p>
   </article>
</li>
</code>```

答: In CSS you can use the float function and the margin function to help you with the image placement. just write your usual CSS code with float: left and float : right to help you.

ContentLicense: CC BY-SA 3.0

Body:
I have image and a text,i need the image on the left and the text on the right..
i cant change the HTML, so i need to do it with CSS only.

        title


问:
Github - Old commits shows up in new pull request
I created branch A of master branch. I made changes and raised pull request to master branch. When I open New Pull request to master branch, I see too many files changes and previous commit with my changes and commit.

I only made changes in 9 files and 1 commit. It shows 87 commit and 30 file changes

I dont know how to solve. I created new branch, off master, took latest and tried. But same result again and again. Please help. Its frustating, I already spend hours

答:
It looks like you are branching off of master and then not updating your branch with the new updates from master. You can get the new commits in your branch and sync up the history with a Rebase -https://git-scm.com/docs/git-rebase

I'd recommend the following process which is easy to follow:

```<code>git checkout master

git pull

git checkout [feature branch]

git rebase origin/master -i

git push origin [feature-branch] --force
</code>```

In the rebase step you can pick all your commits or you can squash them using the s or squash option next to your commits instead of the default pick that appears next to your commits when the text editor opens for your interactive rebase.

After that the history of your master branch should be synced up with the history of your feature branch and only your commit will show up (I recommend squashing all those merge commits- if you follow this rebase workflow you wouldn't even need to do any merges, you can just do rebases- which doesn't add their own commits).

Body:
It looks like you are branching off of master and then not updating your branch with the new updates from master. You can get the new commits in your branch and sync up the history with a Rebase -https://git-scm.com/docs/git-rebase

I'd recommend the following process which is easy to follow:

git checkout master

git pull

git checkout [feature branch]

git rebase origin/master -i

git push origin [feature-branch] --force

In the rebase step you can pick all your commits or you can squash them using the s or squash option next to your commits instead of the default pick that appears next to your commits when the text editor opens for your interactive rebase.

After that the history of your master branch should be synced up with the history of your feature branch and only your commit will show up (I recommend squashing all those merge commits- if you follow this rebase workflow you wouldn't even need to do any merges, you can just do rebases- which doesn't add their own commits).


问:
Check PowerState of Azure VM inside of Azure Policy
I'm working on an Azure Policy to audit running VMs with a custom tag which indicates that the VM is assumed to be decomissioned. The PowerState of the VM is not a normal ARM Attribute but you can find information about the State in the instanceView of the VM:

```<code>{
  "vmAgent": {
    "vmAgentVersion": "2.7.41491.1008",
    "statuses": [
      {
        "code": "ProvisioningState/succeeded",
        "level": "Info",
        "displayStatus": "Ready",
        "message": "GuestAgent is running and processing the extensions.",
        "time": "2021-03-17T08:29:33+00:00"
      }
    ]
  },
  "disks": [
    {
      "name": "DecomissionedVM_OsDisk_1_cfeff76df794480383af685c6062e9b9",
      "statuses": [
        {
          "code": "ProvisioningState/succeeded",
          "level": "Info",
          "displayStatus": "Provisioning succeeded",
          "time": "2021-03-17T08:09:56.3998144+00:00"
        }
      ]
    }
  ],
  "bootDiagnostics": {},
  "statuses": [
    {
      "code": "ProvisioningState/succeeded",
      "level": "Info",
      "displayStatus": "Provisioning succeeded",
      "time": "2021-03-17T08:10:06.4623615+00:00"
    },
    {
      "code": "PowerState/running",
      "level": "Info",
      "displayStatus": "VM running"
    }
  ]
}
</code>```

There is also a valid Alias for the StatusCode which can be used to create a policy definition:

```<code>{
    "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "variables": {
        "policyName": "restrict-startup-of-decomissioned-vms",
        "policyDisplayName": "Restrict startup of decomissioned VMs",
        "policyDescription": "Restrict startup of VMs with 'decomissioned' tag"
    },
    "resources": [
        {
            "type": "Microsoft.Authorization/policyDefinitions",
            "name": "[variables('policyName')]",
            "apiVersion": "2019-09-01",
            "properties": {
                "displayName": "[variables('policyDisplayName')]",
                "policyType": "Custom",
                "description": "[variables('policyDescription')]",
                "metadata": {
                    "category": "General"
                },
                "mode": "All",
                "policyRule": {
                    "if": {
                        "allOf": [{
                                "field": "type",
                                "equals": "Microsoft.Compute/virtualMachines"
                            },
                            {
                                "field": "Microsoft.Compute/virtualMachines/instanceView.statuses[*].code",
                                "contains": "PowerState/running"
                            },
                            {
                                "field": "tags[decomissioned]",
                                "exists": "true"
                            }
                        ]
                    },
                    "then": {
                        "effect": "audit"
                    }
                }
            }
        }
    ]
}
</code>```

The creation and assignment of the policy works, but running machines with the decomissioned tag are not marked as not compliant.

Does anyone know how to correctly use the Microsoft.Compute/virtualMachines/instanceView.statuses[*].code field?

答:
We are not able to use alias: Microsoft.Compute/virtualMachines/instanceView.statuses[*].code since the property would not be returned when the policy sent GET call to the VM.

Here is more details:https://github.com/Azure/azure-policy#resource-type-query-results-incomplete-missing-or-non-standard-format

"Microsoft.Compute/virtualMachines/instanceView
Collection query of this type is missing many properties, which means compliance checks may not work."

Body:
I'm working on an Azure Policy to audit running VMs with a custom tag which indicates that the VM is assumed to be decomissioned. The PowerState of the VM is not a normal ARM Attribute but you can find information about the State in the instanceView of the VM:

{
  "vmAgent": {
    "vmAgentVersion": "2.7.41491.1008",
    "statuses": [
      {
        "code": "ProvisioningState/succeeded",
        "level": "Info",
        "displayStatus": "Ready",
        "message": "GuestAgent is running and processing the extensions.",
        "time": "2021-03-17T08:29:33+00:00"
      }
    ]
  },
  "disks": [
    {
      "name": "DecomissionedVM_OsDisk_1_cfeff76df794480383af685c6062e9b9",
      "statuses": [
        {
          "code": "ProvisioningState/succeeded",
          "level": "Info",
          "displayStatus": "Provisioning succeeded",
          "time": "2021-03-17T08:09:56.3998144+00:00"
        }
      ]
    }
  ],
  "bootDiagnostics": {},
  "statuses": [
    {
      "code": "ProvisioningState/succeeded",
      "level": "Info",
      "displayStatus": "Provisioning succeeded",
      "time": "2021-03-17T08:10:06.4623615+00:00"
    },
    {
      "code": "PowerState/running",
      "level": "Info",
      "displayStatus": "VM running"
    }
  ]
}

There is also a valid Alias for the StatusCode which can be used to create a policy definition:

{
    "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "variables": {
        "policyName": "restrict-startup-of-decomissioned-vms",
        "policyDisplayName": "Restrict startup of decomissioned VMs",
        "policyDescription": "Restrict startup of VMs with 'decomissioned' tag"
    },
    "resources": [
        {
            "type": "Microsoft.Authorization/policyDefinitions",
            "name": "[variables('policyName')]",
            "apiVersion": "2019-09-01",
            "properties": {
                "displayName": "[variables('policyDisplayName')]",
                "policyType": "Custom",
                "description": "[variables('policyDescription')]",
                "metadata": {
                    "category": "General"
                },
                "mode": "All",
                "policyRule": {
                    "if": {
                        "allOf": [{
                                "field": "type",
                                "equals": "Microsoft.Compute/virtualMachines"
                            },
                            {
                                "field": "Microsoft.Compute/virtualMachines/instanceView.statuses[*].code",
                                "contains": "PowerState/running"
                            },
                            {
                                "field": "tags[decomissioned]",
                                "exists": "true"
                            }
                        ]
                    },
                    "then": {
                        "effect": "audit"
                    }
                }
            }
        }
    ]
}

The creation and assignment of the policy works, but running machines with the decomissioned tag are not marked as not compliant.

Does anyone know how to correctly use the Microsoft.Compute/virtualMachines/instanceView.statuses[*].code field?