g | x | w | all
Bytes Lang Time Link
075C clang250424T144529ZExplorer
093Rust211129T002745Zcg909
154INTERCAL211115T123734Zuser1004
059Perl 5211117T153335Zhobbs
042Ruby211117T101520ZG B
00705AB1E legacy211117T095951ZKevin Cr
081Python 3.8211117T033927ZMark Ran
097Python 3211115T163046ZKateba
051R211116T105214ZDominic
071Retina 0.8.2211116T104317ZNeil
020Charcoal211116T101605ZNeil
041JavaScript ES6211115T214711ZArnauld
008Jelly211115T202019Zxigoi

C (clang), 83 80 75 bytes

w;f(long c,*s){for(w=24;w*!(c>>w);w-=8);for(;*s=c>>w&255,w;w-=8)*s++-=256;}

C (gcc), 86 83 78 bytes

w;f(long c,int*s){for(w=24;w*!(c>>w);w-=8);for(;*s=c>>w&255,w;w-=8)*s++-=256;}

Try it online!

Thanks to code shrinking suggestions by @ceilingcat (−5 bytes).

ANSI / ISO C bit widths are assumed. That is, int at least 16 bits and long at least 32 bits.

Input: Code point c, and a pointer to output buffer that can hold at least 4 int values (s[4]).

Output is written to s. Each integer in s is sign-extended from 9 bits to 16 bits. Thus they have a value range [−256, 255].

There are no checks on whether the code point is valid.

A slightly deobfuscated version:

int w;
f(long c, int *s) {
    for (w = 24; w != 0 && (c >> w) == 0; w -= 8) {}
    for (; *s = (c >> w) & 0xFF, w != 0; w -= 8)
        *(s++) -= 256;
}

Note: If people want a more serious implementation, check out this code written by me.

Rust, 93 bytes

|n|(0..4).rev().map(|i|n>>i*8&255|(i>0)as i32*256).skip_while(|&n|n==256).collect::<Vec<_>>()

Try it online!

Ungolfed

|n| {
    (0..4).rev()                 // Iterator over integers from 3 down to 0
    .map(|i|
        (n >> i*8) & 255         // Extract the i'th octet from n
        | ((i > 0) as i32) * 256 // Set the continuation bit if not the last byte
    )
    .skip_while(|&n| n == 256)   // Remove 0x100 bytes at the start
    .collect::<Vec<_>>()         // Evaluate into a vector
}

INTERCAL, 164 162 154 bytes

I made this program before noticing the first comment of the OP. In my comment section the two example programs on both RFC document and my Python implementation says values 0x100, 0x10000, and 0x1000000 are converted incorrectly, while this program converts 256 to [257,0]; which seems to be correct.

DOWRITEIN:1DOCOMEFROM.3PLEASE.1<-!2$:1~#255'~#54613DOSTASH.1DO.2<-#128PLEASE:1<-:1~#65520$#65520(1)DO.3<-':1~:1'~#1(9)DORETRIEVE.1DOREADOUT.1PLEASE(9)NEXT

Try it online!

Usage

Ungolfed

DOWRITEIN:1

DONOTE from label (1) if .3 got at least one bit of one
DOCOMEFROM.3
DONOTE :1~#255 is done first on CLCI
PLEASENOTE obtain lowest 8 bits
DONOTE then do C operation such twospot[1]|spot[2]
DONOTE spot[2] is 256 if second time to visit here 0 otherwise
PLEASE.1<-!2$:1~#255'~#54613
PLEASENOTE this and RETRIEVE statements below
DOSTASH.1
DO.2<-#128
DONOTE like (twospot[1]>>8)
PLEASE:1<-:1~#65520$#65520
(1)DO.3<-':1~:1'~#1

PLEASENOTE finally, until no more .1 stacks
(9)DORETRIEVE.1
DOREADOUT.1
PLEASE(9)NEXT

Algorithm

  1. Write in to the codepoint.
  2. Make a list from backward, using STASH and RETRIEVE statements and a stack.
  3. Then output each item.

Perl 5, 59 bytes

sub{my@o;do{unshift@o,$_[0]%256|256*!!@o}while$_[0]>>=8;@o}

TIO.

Ruby, 62 42 bytes

f=->n,w=0{w+=n%z=256;n<z ?[w]:f[n/z,z]<<w}

Try it online!

05AB1E (legacy), 7 bytes

₁вā€₁¨+

Port of @xigoi's Jelly answer.

I/O as integers.

Try it online or verify all test cases.

Explanation:

₁в       # Convert the (implicit) input-integer to base-256 as list
  ā      # Push a list in the range [1,length] (without popping)
   ¨     # Remove the final item to make the range [1,length)
    €₁   # Map each to 256
         # (we now have a list of 256s of size length-1)
      +  # Add the values at the same positions in the lists together
         # (where the larger list keeps its trailing items as is)
         # (after which this list is output implicitly as result)

In the new version of 05AB1E both €₁ and + wouldn't work here. €₁ will add a 256 before each item instead of replacing them (an alternative could be Ā₁*), and + will cause the final item to be removed, since it will adjust the list to the shortest. In 05AB1E it therefore requires a different approach, which would be 8 bytes instead:

05AB1E, 8 bytes

₁в₁+`₁-)

Try it online or verify all test cases.

Explanation:

₁в       # Convert the (implicit) input-integer to base-256 as list
  ₁+     # Add 256 to each
    `    # Pop and dump the contents of the list separated to the stack
     ₁-  # Subtract 256 from the top item (the last item of the dumped list)
       ) # Wrap the entire stack into a list again
         # (after which this list is output implicitly as result)

Python 3.8, 81 bytes

def f(n):x=n.to_bytes(4,'big');return[i+256 for i in x.lstrip(b'\0')[:-1]]+[x[-1]]

Python 3, 104 103 97 bytes

def f(n):b=f'{0:08}{n:b}';l=len(b);return[256*(i<l-8)+int(b[i:i+8],2)for i in range(l%8or 8,l,8)]

Try it online!

-1 thanks to Kevin Cruijssen

Explanation:

R, 51 bytes

f=function(x,s=0,b=256)c(if(x>=b)f(x%/%b,b),x%%b+s)

Try it online!

Retina 0.8.2, 71 bytes

.+
$*
+`(1+)\1
$+0
01
1
^
7$*0
r`.{8}
¶$&
1A`
.+¶
1$&
1
01
+`10
011
%`1

Try it online! Link includes test suite. I/O is in decimal. Explanation:

.+
$*

Convert to unary.

+`(1+)\1
$+0
01
1

Convert to binary.

^
7$*0
r`.{8}
¶$&
1A`

Split into bytes of 8 bits.

.+¶
1$&

Prefix a 1 to all bytes except the last.

1
01
+`10
011

Convert to unary.

%`1

Convert to decimal.

Charcoal, 20 bytes

I⮌E⮌∨↨N²⁵⁶⟦⁰⟧⁺ι∧κ²⁵⁶

Try it online! Link is to verbose version of code. I/O is in decimal. Would have been 16 bytes if empty output was acceptable for an input of 0. Explanation:

      N                 Input as an integer
     ↨ ²⁵⁶              Converted to base 256 as a list
    ∨                   Logical Or
          ⟦⁰⟧           List of literal `0`
   ⮌                    Reversed i.e. LSB first
  E                     Map over bytes
              ι         Current byte
             ⁺          Plus
                κ       Current index
               ∧        Logical And
                 ²⁵⁶    Literal 256
 ⮌                      Reversed i.e. MSB first again
I                       Cast to string
                        Implicitly print

Converting to groups of 8 bits also takes 20 bytes:

I⮌E⪪⮌⍘N²¦⁸⁺⍘⮌ι²∧κ²⁵⁶

Try it online! Link is to verbose version of code. I/O is in decimal. Explanation:

      N                 Input as an integer
     ⍘ ²                Converted to base 2 as a string
    ⮌                   Reversed i.e. LSB first
   ⪪     ⁸              Split into groups of up to 8 bits
  E                     Map over bytes
             ι          Current byte
            ⮌           Reversed i.e. MSB first again
           ⍘  ²         Converted from base 2
          ⁺             Plus
                κ       Current index
               ∧        Logical And
                 ²⁵⁶    Literal 256
 ⮌                      Reversed
I                       Cast to string
                        Implicitly print

JavaScript (ES6), 41 bytes

If returning an empty array for \$n=0\$ is not acceptable, this version returns [0] instead. Thanks to @tsh for pointing this out.

f=(n,q)=>n|!q?[...f(n>>8,256),n%256|q]:[]

Try it online!


JavaScript (ES6), 38 bytes

f=(n,q)=>n?[...f(n>>8,256),n%256|q]:[]

Try it online!

Jelly, 8 bytes

b⁹+⁹_0¦⁹

Try it online!

Explanation

b⁹+⁹_0¦⁹
b        Convert to base
 ⁹         256
  +      Add
   ⁹       256
      ¦  At index
     0     last
    _      subtract
       ⁹   256